Subsections


6. Modulok (2.4 doc)

Ha a Pythont interaktív módban használod, és kilépsz az értelmezőből, majd újra visszalépsz, minden függvénydefiníció és definiált változó elvész. Emiatt ha nagyobb programot akarsz írni, jobban jársz ha valamilyen szerkesztő programot használsz az értelmező számára előkészteni a bemeneti adatokat, és az értelmezőt úgy futtatod, hogy a bemenet a szövegfájlod legyen.

Ezt a folyamatot script írásnak nevezik. Ahogy a programod egyre hosszabb lesz, előbb-utóbb részekre (fájlokra) akarod majd bontani, a könnyebb kezelhetőség végett. Valószínűleg lesznek praktikus függvényeid, amit már megírt programjaidból szeretnél használni a függvénydefiníciók másolása nélkül.

Ennek a támogatására a Python el tudja helyezni a függvénydefiníciókat egy adott fájlba, amik aztán elérhetők lesznek egy szkriptből, vagy az interaktív értelmezőből. Ezeket a fájlokat moduloknak hívjuk. A modulban használt definíciók importálhatók más modulokba (például a modulok hierarchiájában legfelül lévő main modulba is). (A következő példákhoz: a felhasznált változók mind a legfelső névtérben helyezkednek el, a modulok függvényeit itt futtatjuk, interaktív módban.)

A modul egy olyan szöveges file, ami Python definíciókat és utasításokat tartalmaz. A file neve egyben a modul neve is (a .py kiterjesztést nem beleértve). A programból az aktuális modul neve a __name__ globális változóból elérhető (karakterláncként).

Kérlek egy neked megfelelő szövegszerkesztővel hozd létre a fibo.py fájlt, a következő tartalommal:

# Fibonacci szamok modul

def fib(n):    # kiirja a Fibonacci sorozatot n-ig
    a, b = 0, 1
    while b < n:
        print b,
        a, b = b, a+b

def fib2(n): # visszater a Fibonacci sorozattal, n-ertekig
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result

Most lépj be a Python értelmezőbe, és importáld a fenti modult a következő paranccsal:

>>> import fibo

Ez a parancs a fibo-ban definiált függvényneveket közvetlenül nem emeli be az aktuális szimbólumtáblába; csak magát a modul nevét, fibo-t emeli be. (ford.: mivel a függvények a fibo modul részei, ezért elérhetővé válnak fibo-n keresztül: fibo.fib(szam) )

>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'

Ha egy függvényt gyakran szeretnél használni az importált modulból, hozzárendelheted azt egy lokális függvénynévhez:

>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377


6.1 A modulokról bővebben...

A modulok végrehajtható utasításokat ugyanúgy tartalmazhatnak, mint függvénydefiníciókat.

Ezeket az utasításokat rendszerint a modul inicializálásához használjuk. Kizárólag a modul első importálásakor futnak le. 6.1

Minden modulnak megvan a saját szimbólumtáblája, ami a modulban definiált függvények számára globális. Emiatt a modul létrehozója nyugodtan használhatja a modulban lévő globális változókat, és nem kell aggódnia egy esetleges névütközés miatt. (hiába ugyanaz a neve két változónak, ha külön névtérben vannak, nem írják felül egymás értékét)

Másrészről ha pontosan tudod hogy mit csinálsz, el tudod érni a modul globális változóit a változónév teljes elérési útjának a használatával: modulnev.elemnev.

A modulok importálhatnak más modulokat. Szokás - de nem kötelező - az import utasításokat a modul elején elhelyezni (vagy a szkript elején, lásd később). Az importált modulneveket az értelmező az importáló modul globális szimbólumtáblájába helyezi el.

Az import utasítás egyik felhasználási módja, hogy az importált függvényeket közvetlenül az importáló modul szimbólumtáblájába helyezzük el. Például:

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Az előbbi példa a helyzi szimbólumtáblába nem helyezi el a modul nevét, amiből az importálás történt. (fibo objektum nem jön létre a névtérben)

Ha a modulban lévő összes nevet közvetlenül a helyi szimbólumtáblába szeretnéd importálni, így tudod megtenni:

>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Ha így használod az import utasítást, a forrásmodul minden nevét a helyi szimbólumtáblába emeled, kivéve az aláhúzással kezdődőeket (_).


6.1.1 A Modulok keresési útvonala

Amikor a spam modult importáljuk, az értelmező először az aktuális könyvtárban keresi a spam.py fájlt. Ha itt nem találja, tovább keres a PYTHONPATH környezeti változóban felsorolt könyvtárakban. Ennek a változónak a szintaktisa ugyanolyan, mint a PATH héj-változónak (Linuxon). Egyszerűen könyvtárnevek listáját tartalmazza. Ha a PYTHONPATH változó nincs beállítva, vagy az abban felsorolt könyvtárak a keresett fájlt nem tartalmazzák, a keresés az alapértelmezett könyvtárban folytatódik. Ez már függ az installálástól, Unix-on rendszerint .:/usr/local/lib/python.

Jelenleg a modulokat az értelmező a sys.path változóban felsorolt könyvtárakban keresi. Ez a változó az aktuális könyvtárból (ahonnan a programot futtatjuk), a PYTHONPATH-ban lévő könyvtárakból, és az installálástól függő alapértelmezett könyvtárból áll. Így a Python programoknak módjuk nyílik a modulok keresési útvonalát módosítani, vagy akár teljesen kicserélni.

Fontos megemlíteni, hogy mivel az aktuális könyvtár is a keresési útvonal része, a programnak még véletlenül se legyen ugyanaz a neve, mint valamely standard modulnak. Ebben az esetben ugyanis a Python megkísérli a programot modulként betölteni annak importálásakor, ami hibaüzenethez vezet. További információk: 6.2, ``Standard Modules,''.

6.1.2 ``Lefordított'' Python állományok

Fontos a standard modulokat használó programok indulási idejét lerövidíteni. Ha spam.pyc fájl létezik abban a könyvtárban, ahol spam.py is megtalálható, az értelmező feltételezi, hogy a .pyc fájl a .py fájlnak az előre lefordított változata. (A Python a .py fájlokat először .pyc bájtkódra fordítja, ami már egy bináris, ember számára nem értelmes, olvasható állomány - ezt hajtja végre az értelmező. Ez a működés a Java nyelvhez hasonló konstrukció)

A fordítás során a .pyc fájl ugyanazzal a módosítási idővel jön létre, mint a .py fájl. Ha a két fájl utolsó módosítási ideje különbözik, a .py fájlt újrafordítja a Python.

Rendszerint nem kell tenni semmit a spam.pyc fájl létrehozásáért, mert az a spam.py sikeres bájtkódra fordításakor automatikusan létrejön.

Nem hiba, ha ez az automatizmus látszólag nem működik. Ha bármi oknál fogva a spam.pyc írása félbeszakad, a fájl-t a Python később mindenképpen érvénytelen fájl-nak fogja felismerni. A lefordított .pyc fájl tartalma platform független, ezért a Python modulkönyvtárat nyugodtan megoszthatod különböző achitektúrájú gépek között.

Néhány tipp haladóknak:


6.2 Standard modulok

A Python funkciójuk szerint csoportokba sorolt szabványos modulokkal rendelkezik - egy könyvtárral - részletesen: Python Library Reference - Python referenciakönyvtár a későbbiekben A modulok tételes felsorolása - Module index Néhány modult az értelmezőbe építettünk be, ezeken keresztül olyan funkciók megvalósítása lehetséges, amelyek ugyan nem tartoznak szorosan a nyelvhez, de például az operációs rendszerrel való kapcsolathoz szükségesek - ilyenek például a rendszerhívások.

Ezen modulok függenek a használt operációs rendszertől, hiszen annak működtetéséhez kellenek. Például az amoeba modul csak azokon a rendszereken elérhető, amik támogatják az Amoeba primitívek használatát. A másik figyelemre méltó - és különleges modul a sys , ami minden Python értelmezőbe be van építve. Például a sys.ps1 és sys.ps2 változók tartalmazzák az értelmezőben megjelenő elsődleges és másodlagos prompt karakterláncát:

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print 'Yuck!'
Yuck!
C>

Ez a két változó csak akkor létezik, ha az értelmező interaktív módban fut.

A sys.path változó karakterláncok listáját tartalmazza, melyek meghatározzák az értelmező keresési útvonalát, amit az a modulok importálásakor bejár. Kezdeti értékét a PYTHONPATH környezeti változóból veszi, vagy ha ez nem létezik, akkor az értelmezőbe beépített alapértelmezett útvonalakból. A változó értékét ugyanúgy módosíthatod, mint egy listáét:

>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')


6.3 A dir() függvény

A beépített dir() függvénnyel listázhatjuk ki a modulban definiált neveket. A dir() meghívása után a nevek rendezett listájával tér vissza.

>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__',
 '__stdin__', '__stdout__', '_getframe', 'api_version', 'argv', 
 'builtin_module_names', 'byteorder', 'callstats', 'copyright',
 'displayhook', 'exc_clear', 'exc_info', 'exc_type', 'excepthook',
 'exec_prefix', 'executable', 'exit', 'getdefaultencoding', 'getdlopenflags',
 'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode',
 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache',
 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags',
 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',
 'version', 'version_info', 'warnoptions']

Ha paraméterek nélkül hívjuk meg a dir() függvényt, az aktuális névtérben definiált nevekkel tér vissza:

>>> a = [1, 2, 3, 4, 5]
>>> import fibo, sys
>>> fib = fibo.fib
>>> dir()
['__name__', 'a', 'fib', 'fibo', 'sys']

Fontos, hogy az így kapott lista az összes névfajtát tartalmazza. Változókat, modulokat, függvényeket, stb.

A dir() nem listázza ki a nyelvben előre definiált (beépített) függvényeket és változókat. Ezek a __builtin__ modulban vannak definiálva:

>>> import __builtin__
>>> dir(__builtin__)
['ArithmeticError', 'AssertionError', 'AttributeError',
 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError',
 'Exception', 'False', 'FloatingPointError', 'IOError', 'ImportError',
 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt',
 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented',
 'NotImplementedError', 'OSError', 'OverflowError', 'OverflowWarning',
 'PendingDeprecationWarning', 'ReferenceError',
 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration',
 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError',
 'True', 'TypeError', 'UnboundLocalError', 'UnicodeError', 'UserWarning',
 'ValueError', 'Warning', 'ZeroDivisionError', '__debug__', '__doc__',
 '__import__', '__name__', 'abs', 'apply', 'bool', 'buffer',
 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex',
 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod',
 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float',
 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id',
 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter',
 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min',
 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit',
 'range', 'raw_input', 'reduce', 'reload', 'repr', 'round',
 'setattr', 'slice', 'staticmethod', 'str', 'string', 'sum', 'super',
 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']


6.4 A csomagok

A csomagok adnak lehetőséget a Python modulok névtereinek struktúrálására, a pontozott modulnevek használatával. Például a A.B modulnév hivatkozik a "B" modulra, ami az "A" modulban található (ott importáltuk). Ha a programozók a fenti példa szerint használják a modulokat, nem kell amiatt aggódniuk, hogy egymás globális neveivel ütközés lép fel. Például a több modulból álló csomagok (NumPy, Python Imaging Library...) írói is a pontozott modulnevek használatával kerülik el a változónevek ütközését.

Tegyük fel, hogy egy modulokból álló csomagot akarsz tervezni, hogy egységesen tudd kezelni a hangfájlokat és a bennük lévő adattartalmat. Több különböző hangfájlformátum létezik (rendszerint a kiterjesztésük alapján lehet őket beazonosítani, pl.: .wav, .aiff, .au) - valószínűleg egy bővülő modulcsoportot kell készítened és karbantartanod a fájlformátumok közötti konvertálásra.

There are also many different operations you might want to perform on sound data (such as mixing, adding echo, applying an equalizer function, creating an artificial stereo effect), so in addition you will be writing a never-ending stream of modules to perform these operations. Here's a possible structure for your package (expressed in terms of a hierarchical filesystem):

Ráadásul még többfajta műveletet is el kell tudnod végezni a hanganyagon, például keverést, visszhang készítését, hangszínszabályzást, művészeti sztereo effekteket - szóval a fentiek tetejébe még írni fogsz egy végeláthatatlan modulfolyamot, ami ezeket a műveleteket elvégzi. A csomagok egy lehetséges struktúrája - a hierarchikus fájlrendszereknél használatos jelöléssel:

  Sound/                          Legfelső szintű csomag
        __init__.py               a sound csomag inicializálása
        Formats/                  A fájlformátum konverziók alcsomagja
                __init__.py
                wavread.py
                wavwrite.py
                aiffread.py
                aiffwrite.py
                auread.py
                auwrite.py
                ...
        Effects/                  A hangeffektek alcsomagja
                __init__.py
                echo.py
                surround.py
                reverse.py
                ...
        Filters/                  A szűrők alcsomagja
                __init__.py
                equalizer.py
                vocoder.py
                karaoke.py
                ...

A csomag: olyan hierarchikus könyvtárszerkezet, amely egymással összefüggő modulokat tartalmaz.

Egy csomag importálása során a Python bejárja a sys.path változóban szereplő könyvtárakat, a csomag alkönyvtárak után kutatva. A sys.path az előre meghatározott keresési útvonalakat tartalmazza.

A Python az __init__.py fájlok jelenlétéből tudja, hogy egy könyvtárat csomagként kell kezelnie - és ez a fájl segít abban is, hogy az alkönyvtárakban lévő csomagokat is érzékelje a Python.

A legegyszerűbb esetben az __init__.py egy üres fájl, de tartalmazhat és végrehajthat a csomaghoz tartozó inicializáló kódot, vagy beállíthatja az __all__ változót (lásd lejjebb).

A csomag felhasználói egyenként is importálhatnak modulokat a csomagból:

import Sound.Effects.echo

Ez betölti a Sound.Effects.echo almodult. A hivatkozást teljes útvonallal kell megadni.

Sound.Effects.echo.echofilter(input, output, delay=0.7, atten=4)

Egy másik alternatíva almodulok importálására:

from Sound.Effects import echo

Ez szintén betölti az echo almodult, és elérhetővé teszi a csomagnevek nélkül is (nem kell a Sound.Effects előtag).

echo.echofilter(input, output, delay=0.7, atten=4)

Van még egy lehetőség a kiválasztott függvény importálására:

from Sound.Effects.echo import echofilter

Ez szintén betölti az echo almodult, de a echofilter() függvény közvetlenül elérhetővé válik:

echofilter(input, output, delay=0.7, atten=4)

Fontos, hogy a from csomag import elem használatakor az elem az importált csomag almodulja (submodule) vagy alcsomagja (subpackage) is lehet, vagy valamilyen más, a csomagban definiált 'elem' nevű objektum, például függvény, osztály vagy változó.

Az import utasítás először ellenőrzi, hogy az importálandó elem definiálva van-e a csomagban. Ha nem, akkor az elemről feltételezi, hogy az egy modul, és megkísérli azt betölteni. Ha a modul keresése sikertelen, ImportError kivétel váltódik ki.

Ezzel ellentétben az import elem.alelem.alelem_aleleme utasításforma használatakor az utolsó alelem_aleleme kivételével mindegyik elemnek csomagnak kell lennie. Az utolsó elem lehet modul vagy csomag is, de a fentiekkel ellentétben nem lehet osztály, függvény vagy definiált változó.


6.4.1 Egy csomag összes elemének importálása

Mi történik, amikor a programozó kiadja a from Sound.Effects import * utasítást? Ideális esetben az értelmező a fájlrendszerben megtalálja a csomagban lévő almodulokat, és mindet importálja.

Sajnos ez a művelet Mac vagy Windows platformon nem igazán jól működik - ennek oka a fájlrendszerek hiányosságában keresendő, hiszen az nem tartalmaz pontos információkat a fájlnév pontos kisbetűs - nagybetűs írásmódjáról. A fenti platformokon nincs garantált módszer annak kiderítésére, hogy az VISSZHANG.PY fájlt visszhang, Visszhang vagy VISSZHANG modulként kell-e importálni.

Például a Windows 95 egyik bosszantó tulajdonsága, hogy minden fájlnevet nagy kezdőbetűvel jelenít meg. A DOS 8+3 betűs névhosszúsága szintén érdekes problémákat vet fel hosszú modulnevek esetében.

A csomagkészítők számára az egyedüli megoldás az, ha a csomagot egyértelmű index-el látják el. Az import utasítás a következő szabályokat használja: ha a csomag __init__.py állományának kódjában szerepel az __all__ nevű lista, az abban felsorolt nevek lesznek az importálandó modulnevek a from package import * utasítás végrehajtásakor.

A csomag készítőjének feladata, hogy ezt a listát naprakészen tartsa, mikor a csomag újabb verzióját készíti. A csomagkészítők dönthetnek úgy, hogy ezt a funkciót nem támogatják, ha valószínűtlennek tartják hogy valaki az import * utasítást használja a csomagra. Például a Sounds/Effects/__init__.py fájl a következő kódot tartalmazhatja:

__all__ = ["echo", "surround", "reverse"]

A fentiek értelmében a from Sound.Effects import * importálni fogja a három felsorolt almodult a Sound csomagból.

Ha az __all__ lista nem meghatározott, a from Sound.Effects import * utasítás nem importálja a Sound.Effects csomag összes almodulját az aktuális névtérbe - csupán azt biztosítja, hogy a Sound.Effects csomag importálva legyen (talán, ha az __init__.py inicializáló kódból adod ki az utasítást ???) és aztán a csomagban található összes nevet importálja.

Ebbe beleértendő minden név, amit az __init__.py-ben vagy az almoduljaiban definiáltak. Szintén importálva lesz a csomag minden almodulja, amit a from Sound.Effects import * utasítás előtt importáltunk.

Figyeljük meg, mi történik ebben a kódban:

import Sound.Effects.echo
import Sound.Effects.surround
from Sound.Effects import *

Ebben a példában az 'echo' és a 'surround' modulokat az értelmező a helyi (belső) névtérbe importálja, mert a Sound.Effects csomag részei voltak a from...import utasítás végrehajtásakor. (Ez szintén működik, amikor az __all__ változó definiálva van)

Jó tudni, hogy az import * importálási mód használata kerülendő, mert a kódot nehezen olvashatóvá teszi. Ámbár ennek az importálási módnak a használatával egyszerűbben dolgozhatunk az értelmező interaktív módjában, egyes modulokat úgy terveznek, hogy csak az __all__ változóban megadott neveket exportálják.

Emlékezzünk rá, hogy semmi probléma nincs a from Package import specific_submodule szerkezet használatával! Valójában ez az ajánlott importálási mód, hacsak az importáló modulnak nincs szüksége különböző csomagokból származó azonos nevű almodulok használatára.

6.4.2 Csomagon belüli hivatkozások

Az almodulok gyakran hivatkoznak egymásra - például a surround modul elképzelhető hogy használja az echo modult.

Valójában ha a példához hasonló hivatkozás történik, az import utasítás először a már importált csomagokban keres, mielőtt a standard modulok keresési útvonalát végignézi.

Ennélfogva a surround modul egyszerűen használhatja az import echo vagy a from echo import echofilter importálási utasítást. Ha az importált modul nem található meg az aktuális csomagban (az a csomag, amelyiknek az aktuális modul is része - almodulja), az import utasítás a felső szintű modulokban keresi a megadott nevet.

Amikor a csomagok kisebb egységekből - alcsomagokból épülnek fel, a fenti példában szereplő Sound csomaghoz hasonlóan, az almodulok egymásra teljes - pontozott, hierarchikus nevükkel kell hivatkozzanak. Például ha a Sound.Filters.vocoder-nek használnia kell a Sound.Effects csomagban található echo modult, a következőképpen érheti azt el: from Sound.Effects import echo

6.4.3 Modulok, amelyek több, különálló könyvtár moduljaiból épülnek fel

A csomagok rendelkeznek egy egyedi tulajdonsággal, melyet __path__ -nak hívunk. Ez egy lista, amelyben az __init__.py fájlt tartalmazó könyvtár nevét találjuk - mielőtt az aktuális fájlban lévő kód végrehajtódna.

Ez egy módosítható változó, amely befolyásolja a csomagban található modulok és alcsomagok keresését.

Bár erre a lehetőségre ritkán van szükség, a csomagot újabb modulokkal egészíthetjük ki vele.



Footnotes

... le.6.1
Valójában a függvénydefiníciók szintén végrehajtható utasítások; A függvény neve a végrehajtás során kerül bele a modul globális szimbólumtáblájába.
See About this document... for information on suggesting changes.