Python


Moduly

Ako sme si už povedali v prvej časti seriálu, programy, ktoré nechceme stratiť po opustení interpreta (ak chceme časti ich kódu využiť viackrat) píšeme v textovom editore a ukladáme do súboru, najlepšie s príponou .py. Tento postup sa nazýva skriptovanie. Keď sa časom skritpy zväčšia, zvyčajne sa kvôli ľahšej správe rozdelia na viaceré súbory. V rámci jedného súboru nazývame zoskupenia takýchto medzi sebou súvisacich skritpov modul. Pomocou modulov teda ľahko spravujeme naše programy. Modul môže využívať definície z iných modulov. Prácu s s modulmi si ukážeme na funkciách prvocislo a prvocislo2 z predchádzajúceho dielu seriálu. Tieto funkcie umiestnime do súboru modul1.py v adresári, z ktorého spustíme Pythona. Súbor modul1.py bude by mal vyzerať takto:

#jednoduche funkcie na pracu s prvocislami

def prvocislo(n):
       "vypise ci je n prvocislo"
       for x in range(2,n):
               if n % x == 0:
                       print n, '=', x, '*', n/x
                       break
       else:
               print n, 'je prvocislo'


def prvocislo2(n):
        "vrati pole s prvocislami do n"
        vysledok=[]
        for n in range(2, n):
                for x in range(2,n):
                        if n% x == 0:
                                break
                else:
                        vysledok.append(n)
        return vysledok

Pre každý importovaný modul vytvorí Python 4 globálne premenné, pričom pre nás sú zaujímavé 3. Meno modulu (napr. modul1) je prístupné cez globálnu premennú __name__. V premennej __file__ je meno importovaného súboru (napr. modul1.py). Ako sme si už ukázali v minulých číslach pomocou __doc__ pristupujeme k dokumentačnému reťazcu objektu. K týmto premenným pristupujeme konštrukciou meno_modulu.__premenna__.

>>> import modul1
>>> modul1.__file__
'C:\\Program Files\\Python\\modul1.pyc'

Asi ste postrehli, že prípona modulu je .pyc a nie .py. Prečo je to tak, je vysvetlené v odstavci _Kompilované pythonovské súbory_.

Na tomto mieste je tiež vhodné si povedať, čo sú tabuľky symbolov. Jedná sa o doplnenie minulého čísla, kde sme si pohovorili o lokálnych premených. Pre každý blok v Pythone sa vytvorí tabuľka symbolov, ktorá obsahuje všetky indentifikátory v danom bloku. Takáto tabuľka obsahuje teda lokálne premenné, preto hovoríme, že je to lokálna tabuľka symbolov. Globálne premenné obsahuje globálna tabuľka symbolov. Globálne premenné sú prístupné z každej časti nášho programu, lokálne len z bloku kde boli definované. Po ukončenií bloku zaniknú jeho lokálne premenné. Ak tomu chceme zabrániť, pomocou príkazu global (napr. global a) definuje globálnu premennú v bloku:

>>> def a():

global x #globalna premenna

def funkcia():

print "asdf"

x=funkcia

>>> funkcia()

>>> x()

asdf

Všetky definície (funkcie prvocislo a prvocislo2) z modulu modul1 importujeme príkazom import:

>>> import modul1

a používame nasledovne:

>>> modul1.prvocislo(23)
23 je prvocislo
>>> a = modul1.prvocislo2(10)
>>> a
[2, 3, 5, 7]

Ako ste si už určite všimli, k definíciam z modulov importovaných pomocou príkazu import pristupujeme podobne ako ku globálnym premenným modulu a to pomocou konštrukcie meno_modulu.meno_definície. Kedže vypisovať pri každom použití definíce meno_modulu môže byť pomerne nepraktické (ak napr. plánujeme využívať importovanú funkciu viackrát), priradíme jej nové meno:

>>> prvocislo = modul1.prvocislo

Importovať však nemusíme rovno celé moduly. Ak plánujeme využívať len niektoré definície z daného modulu, použijeme príkaz from meno_modulu import definícia1, definícia2, ..., definíciaN, pričom si pri používaní takto importovaných definícií ušetríme vypisovanie mena modulu v samotných príkazoch.

>>> from modul1 import prvocislo, prvocislo2
>>> prvocislo(78)
78 = 2 * 39

Pomocou príkazu from meno_modulu import * importuje všetky definície z daného modulu, ktoré nezačínajú znakom "_".

>>> from modul1 import *

>>> prvocislo(2)
4 = 2 * 2

 

Kde hľadá Python moduly?

Pod Unix OS je cesta k modulom uložená v shellovskej premennej $PYTHONPATH. Syntax je tá istá ako u premmenej $PATH, ktorá udáva cestu k spustiteľným súborom. Ešte pred cestou v premennej $PYTHONPATH sa moduly hľadajú v adresári, kde sme spustili interpreta Pythona. Pod Windows je cesta k modulom udaná v databáze Registry, pričom moduly sa tiež najprv hľadajú v adresári odkiaľ sme spustili interpret. S cestou k modulom pracujeme pomocou poľa append z modulu sys:

>>> import sys

>>> sys.path.append(_c:\\_) #moduly sa budu hladat aj na c:\

Modul sys sprístupňuje funkcie a premenné, ktoré úzko súvisia s interpretom Pythona, okrem ďalších aj premenné ps1 a ps2, ktoré definujú výzor promptu (výzva interpreta na zadanie príkazu). Tieto premenné su prístupné len vtedy, ak sa nachádzame v interaktívnom režime.

>>> print sys.ps1; print sys.ps2

>>>

...

>>> sys.ps1="zadaj nieco >"

zadaj nieco >

 

Štandardné moduly

Jedným z najväčších lákadiel Pythona sú asi štandardné moduly. Aby sme si pre väčšinu bežných operácií nemuseli písať vlastné funkcie, dodáva sa spolu s Pythonom kolekcia modulov, ktoré nám uľahčujú prácu s reťazcami, sieťovými protokolmi, kryptografiou, komprimovanými súbormi, GUI aplikáciami. Sprístupnia nám matematické funkcie, debugger, profiler, regulárne výrazy atď. K štandardným modulom neoddeliteľne patrí aj vyššie spomenutý modul sys. Väčšina týchto modulov je dostupná pre všetky platformy (Unix, Windows, MacOS), niektoré su však dostupné len pre ten či onen OS. Mená a popis všetkých štandardných modulov nájdete v dokumentácii k Pythonu.

"Kompilované" pythonovské moduly

Python, podobne ako aj ostatné skriptovacie jazyky, je podstatne pomalší ako tie jazyky, ktorých zdrojové kódy sa kompilujú. Pretože rýchlosť je veľmi dôležitým aspektom dobrého programu, modernejšie skriptovacie jazyky kompilujú kód do akéhosi "binárneho medzikódu_ - bajtkódu, ktorý potom vykonávajú. Pri použití nejakého modulu (pri jeho importovaní) sa v adresári, kde sa dotyčný modul nachádza, hľadá rovnomenný súbor s príponou .pyc. Takýto súbor obsahuje bajtkód rovnomenného súboru s príponou .py. Ak súbor s príponou .pyc neexistuje, Python ho automaticky vytvorí. Súbor .pyc obsahuje aj čas poslednej modifikácie rovnomerného súboru .py. Ak sa čas v súbore s príponou .pyc nezhoduje s časom modifikácie .py súboru, súbor .pyc bude prepísaný novou "kompilovanou" verziou súboru .py. Spustením Pythona s prepínačom " -O" (python -O) spôsobíme, že "binárny medzikód" sa bude viac optimalizovať (preto prepínač "O" z anglického slova optimize). Tento medzikód sa potom nebude ukladať do súboru s príponou .pyc, ale do súboru s príponou .pyo (meno súboru bude samozrejme to isté čo meno modulu). Aby sme moli .pyo súbory importovať, je treba spustiť Python s hore uvedením argumentom __O_. Okrem rýchlosti spočíva výhoda používania "kompilovaných" v tom, že na importovanie modulu nie je potrebný jeho zdrojový kód (súbor z príponou .py). Na použitie modulu nám preto stačí jeho binárny medzikód (v súbore s prínou .pyc alebo .pyo), takto nemusíme prezradiť algoritmy nášho programu.

dir() funkcia

Vstavaná funkcia dir() slúži na zistenie mien, ktoré definuje nejaký modul. Vracia abecedne zoradené pole reťazcov. Príklad:

>>> dir(modul1)
['__builtins__', '__doc__', '__file__', '__name__', 'prvocislo', 'prvocislo2']

Bez argumentov vráti funkcia dir() práve definované mená:

>>> a,b,c = 3,12,-9
>>> import sys, modul1
>>> dir()
['__builtins__', '__doc__', '__name__', 'a', 'b', 'c', 'modul1', 'sys']

Funkcia dir() nevracia mená vstavaných premenných a funkcií (napr. tuple, range). Aby sa tak stalo, musíme importovať štandardný modul __builtin__ a naňho použiť funkciu dir():

>>> import __builtin__
>>> dir(__builtin__)

Balíčky

Možnosti štruktúrovania zdrojových kódov v Pythone sa nekončia pri modulov. Môže sa stať, že moduly sa rozrastú do neúnosných rozmerov a samé o sebe nebudú môcť poskytnúť dostatočné možnosti na štruktúrovanie našich programov. V takom prípade nám prídu vhod tzv. balíčky (packages), adresáre so zoskupením so sebou súvisiacich modulov. Práca s balíčkami je podobná práci s modulmi. Je nevyhnutná na rozsiahlych projektoch. Z priestorových dôvodov (v seriáli neplánujem písať programy s 1000 riadkami a viac;) sa balíčkami nebudem zaoberať. Ak sa chcete bližšie oboznámiť s balíčkami, odporúčam dokumentáciu Pythonu.

Martin Uzak

[Pridať príspevok k článku][Verzia pre tlač]