Subsections

 
6. Moduly

Jak jste si jistě všimli, po ukončení prostředí jazyka Python přijdete o všechny proměnné a funkce, které jste si definovali. Proto, píšete-li delší programy, je vhodnější zdrojový kód uložit do souboru a interpretr nasměrovat na tento soubor. Ten se pak v terminologii jazyka Python nazývá skript.6.1. Tím, jak se program stává delší a delší, se často vyskytne potřeba ho rozdělit na několik (relativně) nezávislých částí. Tyto části se nazývají moduly a lze je použít i pro vytvoření sdílených knihoven kódu, kdy jednu funkci definovanou v globálně přístupném modulu může používat kterýkoli jiný modul, jenž k němu má přístup. Funkce a proměnné mohou být z modulu importovány (zavedeny) do jiných modulů, která je pak můžou používat obvyklým způsobem.

Modul je soubor obsahující kód jazyka Python (např. definice funkcí a další příkazy). Je zvykem ukládat moduly do souborů s příponou .py, pak jméno souboru bez přípony znamená jméno modulu.6.2. Jako příklad má poslouží následující kód (uložený například v souboru fibo.py):

# Modul obsahující funkce pro výpočet Fibonacciho rozvoje

def fib(n):    # vytiskne Fibonacciho rozvoj do čísla n
    a, b = 0, 1
    while b < n:
        print b,
        a, b = b, a+b

def fib2(n): # vrátí Fibonacciho rozvoj do čísla n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result

Nyní přejděte do adresáře, v němž se nachází váš soubor fibo.py, spusťte interpretr Pythonu a zaveďte modul následujícím příkazem:

>>> import fibo

Tento příkaz vytvoří v lokálním oboru jmen nové jméno (proměnnou) s názvem fibo. Toto jméno odkazuje na objekt modulu, tento objekt již obsahuje funkce a proměnné definované modulem fibo. Na tyto objekty se odkazujeme použitím tečkové notace:

>>> 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'

Pokud nějakou proměnnou nebo funkci budeme potřebovat častěji, je možné si vytvořit lokální jméno odkazující na objekt uvnitř modulu. Přístup k lokálním proměnným je rychlejší a hlavně ušetříte svojí klávesnici, protože nebudete muset neustále opisovat jméno modulu:

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

 
6.1 Používáme moduly

Moduly mohou obsahovat libovolný kód, jejich použití se tedy neomezuje na pouhé definování řady funkcí. Před prvním zavedením modulu interpretr nalezne soubor obsahující modul, načte ho a spustí všechny příkazy, které obsahuje. Tento proces se nazývá inicializace modulu. Při inicializaci vznikají objekty reprezentující funkce uvnitř modulu a je možné při ní nastavit i globální proměnné modulu do určitého stavu. Pokud chce program importovat modul, který je již zinicializován, nedojde k opětovnému spuštění kódu, nýbrž se použije objekt modulu vytvořený při inicializaci.

Zavedením modulu vznikne nový prostor jmen určený pro globální proměnné tohoto modulu. Díky tomuto mechanismu může autor modulu používat libovolné názvy proměnných a přesto nedojde ke kolizi s proměnnými jiného modulu. Proměnné v tomto jmenném prostoru jsou přístupná za použití objektu modulu (klasicky jako jméno_modulu.proměnná). Nedoporučuje se ovšem libovolným způsobem modifikovat soukromé proměnné modulu, mohli byste totiž narušit konzistenci dat modulu a ten by mohl začít chybně pracovat.

Je samozřejmé, že moduly mohou importovat jiné moduly. V Pythonu je zvykem umístit veškeré příkazy import na začátek modulu či skriptu. Definice jazyka to ovšem nevyžaduje, uznáte-li za vhodné, můžete příkaz import použít například ve větvi příkazu if nebo uvnitř funkce.

Jak jsme si řekli výše, příkaz import zavede do lokálního prostoru jmen objekt modulu. Existuje ale i varianta příkazu import, která rovnou zavede některé (popř. všechny) objekty z určitého modulu. Nemusíme tedy používat přiřazení pro vytvoření lokálního jména:

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

Toto použití příkazu import nevytvoří jméno, odkazující na objekt modulu, v příkladě výše je tedy proměnná fibo (reprezentující modul fibo) nedefinována.

Pro zavedení všech jmen z modulu je zde další varianta příkazu import:6.3

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

Tento příkaz zavede z modulu všechna jména s výjimkou těch, která začínají znakem podtržítko. Je třeba podotknout, že tento způsob použití modulů je velmi zrádný. Jednak není známo, na kterém místě je která proměnná definována a jednak již může dojít ke kolizi jmen a proto u některých modulů je výslovně zakázáno použití from ... import *. Snažte se proto používání tohoto příkazu omezit pouze na interaktivní sezení a ve skriptech ho raději vůbec nepoužívejte.

 
6.1.1 Vyhledávání modulů

 Co se stane, pokud importujeme modul fibo poprvé? Kde všude interpretr hledá soubory obsahující definici tohoto modulu? Především nejprve se interpretr podívá do pracovního adresáře, jestliže zde najde soubor fibo.py, veškerá jeho práce končí a pokusí se zavést tento modul.

Pokud však tento soubor v tomto adresáři nenalezne, začne ho vyhledávat podle přesných pravidel specifikovaných definicí jazyka. Tedy: nejprve se podívá na proměnnou prostředí PYTHONPATH, která by měla mít stejnou syntaxi jako proměnná prostředí PATH. Není-li proměnná PYTHONPATH nastavena nebo v adresářích, které specifikuje, není požadovaný soubor nalezen, pokračuje vyhledávání v implicitní cestě. Tu specifikuje proměnná sys.path, jde o seznam řetězců reprezentujících adresáře. Obsah této proměnná je závislý na instalaci interpretru a jeho nastavení v modulu site. Může vypadat třeba takto: ['/usr/lib/python2.2', '/usr/lib/python2.2/plat-linux2'].

Je třeba důsledně dbát na to, aby nějaký soubor v pracovním adresáři neměl stejné jména jako nějaký standardní modul. Uzavřeli bychom si tak cestu k tomuto standardnímu modulu, protože při pokusu o zavedení tohoto modulu bychom ve skutečnosti obdrželi modul ze souboru v pracovním adresáři. Pro více informací o standardních modulech nahlédněte do sekce 6.2.

Pokud interpretr požadovaný modul nenalezne, dojde k výjimce, která se rozšíří z příkazu import6.4. Obdobně je tomu i v případě, kdy se požadovaný modul podařilo nalézt, ale při jeho inicializaci došlo k výjimce. Zde je třeba dávat pozor na to, že přestože modul nebyl korektně zinicializovaný, při dalším pokusu o jeho zavedení se již druhá inicializace konat nebude a modul bude možné používat nezinicializovaný.

6.1.2 "Kompilované" moduly

Pro zrychlení spouštění (nikoli běhu!) krátkých programů používajících velké množství standardních modulů používá Python soubory s příponou .pyc, tzv. kompilované moduly. Pokud se kód pokusí zavést modul fibo a interpretr najde vedle souboru fibo.py i soubor fibo.pyc, považuje tento soubor za zkompilovaný modul. Proto porovná čas modifikace souboru fibo.py s časem zaznamenaným v souboru fibo.pyc. Jestliže jsou tyto časy shodné, rozhodne, že soubor fibo.pyc byl vytvořen ze souboru fibo.py a použije ho místo něj. Tím dojde k významnému urychlení zavedení modulu, není třeba jeho kód znovu překládat do bytekódu, protože se použije již přeložená verze.

O vytvoření souboru fibo.pyc se programátor nemusí vůbec starat, interpretr ho vytváří zcela sám kdykoli, když se mu podaří kód souboru fibo.py úspěšně přeložit do bytového kódu. Jestliže se soubor nepodaří vytvořit (důvodem může být plný disk nebo nedostatečná práva uživatele), nedojde k chybě, protože při příštím importu modulu bude byte kód vytvořen znovu. Stejně tak tomu bude i v případě, kdy se sice soubor fibo.pyc podaří vytvořit, ale nebude možné ho zapsat celý, případně jeho obsah bude chybný, interpretr na základě kontrolních součtů tento soubor vyhodnotí jako nevyhovující a po importu souboru fibo.py ho vytvoří znovu.

Následuje několik důležitých poznámek týkajících se přeložených modulů:

 
6.2 Standardní moduly

Základní distribuce Pythonu obsahuje velké množství modulů (jsou popsány v samostatném dokumentu Python Library Reference). Díky nim je možné realizovat množství úloh spojených s internetem, unixovými databáze dbm, prací se soubory, operačním systémem a mnoho a mnoho dalších.

Některé moduly jsou přímo součástí interpretru, umožňují totiž přístup k operacím, které nejsou přímo součástí jádra prostředí, ale jsou mu velice blízká (např. v dané aplikaci závisí na rychlosti vykonávání nebo je třeba volat funkce operačního systému či dalších knihoven). Zahrnutí těchto modulů je závislé na konfiguraci a překladu interpretru. (Například modul Tkinter určený jako rozhraní ke grafické knihovně Tk je přítomný pouze na systémech s knihovnou Tk).

Mezi všemi moduly najdeme jeden, který nabízí samotné jádro běhového systému, modul sys a obsahuje ho každý interpretr. Jeho proměnné sys.ps1 a sys.ps2 umožňují v interaktivním módu nastavení primární a sekundární výzvy interpretru:

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

Jak již jistě víte, proměnná sys.path je seznam řetězců, který určuje cesty v nichž interpretr vyhledává moduly. Je inicializována z proměnné prostředí PYTHONPATH příp. je nastavena v modulu site. Jde o klasický seznam, který můžete měnit běžnými operacemi definovanými nad seznamy:

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

 
6.3 Funkce dir()

Interní funkci dir() použijete v případě, že chcete zjistit všechna jména, která jsou definována uvnitř nějakého objektu. Tato funkce vrací seznam řetězců setříděný podle abecedy, jeho používání reprezentuje následující příklad:

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

Bez argumentů vrátí seznam jmen, které jsou definovány v aktuálním prostoru jmen:

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

Seznam vrácený funkcí dir() zahrnuje všechna jména definovaná v objektu, nejde tudíž pouze o proměnné, ale i o funkce, moduly, třídy apod. Do tohoto seznamu nejsou zahrnuta jména interních funkcí a proměnných (tj. těch definovaných modulem __builtin__). Pokud potřebujete seznam interních funkcí použijte

>>> import __builtin__
>>> dir(__builtin__)
['ArithmeticError', 'AssertionError', 'AttributeError',
 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError',
 'Exception', 'FloatingPointError', 'IOError', 'ImportError',
 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt',
 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented',
 'NotImplementedError', 'OSError', 'OverflowError', 'OverflowWarning',
 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError',
 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
 'SystemExit', 'TabError', 'TypeError', 'UnboundLocalError',
 'UnicodeError', 'UserWarning', 'ValueError', 'Warning',
 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__',
 '__name__', 'abs', 'apply', 'buffer', 'callable', 'chr', 'classmethod',
 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr',
 'dict', 'dir', 'divmod', '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', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange',
 'zip']

 
6.4 Balíčky

Balíčky jsou logickým rozšířením mechanismu Pythonových modulů. V Pythonu je totiž široce používána "tečková notace" a právě balíčky umožňují hiearchickou organizaci modulů.

Například modul se jménem A.B znamená modul pojmenovaný "B" v balíčku "A". Balíčky umožňují dekompozici rozsáhlých knihoven do menších souborů - modulů. Autoři jednotlivých modulů se nemusí zajímat o jména globálních proměnných jiných modulů v tomtéž balíčku, jazyk zajišťuje vzájemnou "izolaci" balíčků mezi sebou. Proto se například autoři jednotlivých modulů rozsáhlých balíčků (např. NumPy nebo Python Imaging Library) nemusí obávat střetu jmen svých globálních proměnných s proměnnými jiného autora.

Představte si modelovou situaci: chcete navrhnout balíček (kolekci modulů) pro manipulaci se zvukovými soubory a zvukovými daty obecně. Poněvadž existuje mnoho různých zvukových formátů, potřebujete vytvořit a spravovat kolekci modulů pro konverzi mezi těmito formáty. Také si můžete představit mnoho operací, které lze se zvukovými daty provádět (např. mixování stop, přidávání ozvěny, aplikování ekvalizéru ...). Postupem času si vytvoříte mnoho modulů pro tyto činnosti. Pro jejich organizaci je mechanismus balíčků naprosto ideální. Zde je možná struktura vašeho balíčku (zobrazená jako hiearchický souborový systém):

Sound/                          Hlavní balíček
      __init__.py               Inicializace balíčku
      Formats/                  Balíček pro konverzi souborových formátů
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      Effects/                  Balíček pro zvukové efekty
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      Filters/                  Balíček filtrů
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

Jistě se ptáte, co znamenají soubory __init__.py. Python podle nich rozpoznává adresáře obsahující balíčky. To zabraňuje nedorozuměním, kdy Python považoval libovolný adresář nacházející se v jeho cestě za balíček. V nejjednodušším případě je soubor __init__.py pouhopouhý prázdný soubor, můžete sem ale umístit inicializační kód balíčku nebo nastavit proměnnou __all__ (její význam je popisován později).

Uživatelé balíčku z něj mohou přímo importovat jednotlivé moduly:

import Sound.Effects.echo

Tento příkaz načte modul Sound.Effects.echo. Jeho proměnné a funkce však musí být odkazovány plným jménem:

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

Jinou možností je přímé importování modulu z balíčku:

from Sound.Effects import echo

Tento příkaz také načte modul echo a učiní jej přístupným za použití jeho jména. Funkce v něm definované můžete používat třeba následovně:

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

Další cestou je importování určité funkce nebo proměnné přímo:

from Sound.Effects.echo import echofilter

Tento příkaz opět načte modul echo, ale učiní jeho funkci echofilter() přístupnou přímo:

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

Na závěr podotkněme, že při importování nějakých jmen (proměnných, modulů apod.) za použití příkazu import můžeme na místě objektu, z něhož chceme import provést uvést pouze balíček nebo modul. Příkaz "from objekt_různý_od_modulu_či_balíčku import jeho_atribut" je považován za běhovou chybu a z místa jeho použití se rozšíří výjimka. Jako náhradu takovéto konstrukce lze použít "jeho_atribut = objekt_různý_od_modulu_či_balíčku.jeho_atribut".

 
6.4.1 Importování * z balíčku

Co se nyní stane, napíše-li uživatel from Sound.Effects import *? Nejideálnější, ale nereálná cesta by mohla vypadat takto: interpretr projde souborový systém, najde moduly patřící tomuto balíčku a zavede je. Bohužel. Na platformách Mac a Windows totiž souborový systém neuchovává informace o velikosti písmen jmen souborů! Neexistuje zde žádná záruka, že soubor echo.py nebude importován jako modul echo, Echo nebo dokonce ECHO. V operačním systému DOS se k těmto problémům ještě přidává omezení délky jmen souborů na 8 znaků + 3 znaky přípony.

Python proto nabízí své platformně nezávislé řešení: autor balíčku prostě interpretru sdělí, jaké moduly balíček obsahuje. Příkaz import byl modifikován a používá následující konvenci: jestliže kód v souboru __init__.py (vzpomeňte si, že jde o inicializační soubor celého balíčku) definuje proměnnou pojmenovanou __all__ typu seznam, pak je tato proměnná považována za výčet všech modulů, které mají být importovány při vykonání příkazu "from balíček import *". Udržování tohoto seznamu v aktuálním stavu je povinností autora balíčku. Ten se může rozhodnout ho dokonce nepodporovat, pokud považuje importování * za bezvýznamné. Například soubor Sounds/Effects/__init__.py by mohl obsahovat následující kód:

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

Tím interpretru říkáme, že balíček Sound.Effects obsahuje celkem tři moduly: echo, surround a reverse.

Jestliže proměnná __all__ není definována, příkaz from Sound.Effects import * pouze spustí inicializační kód balíčku (soubor __init__.py) a posléze zavede všechna jména definovaná tímto kódem. Tento kód může explicitně zavést nějaký z modulů balíčku do hlavního prostoru jmen balíčku. Import všech jmen pak zavede i tento modul.

Existuje ještě jedna nuance při importování modulů z balíčků. Pokud před provedením from balíček import * zavedete explicitně nějaký modul tohoto balíčku, bude při importování všech jmen z modulu mezi nimi i tento modul. Vše snad názorně vysvětlí následující kód (předpokládá, že soubor __init__.py je prázdný soubor):

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

Po posledním příkazu import budou v lokálním prostoru jmen načteny moduly echo a surround, protože již byly načteny předchozími příkazy import. (Toto chování je nezávislé na proměnné __all__ a je vcelku logické, pokud jsme nějaký modul zavedly a interpretr o něm "nevěděl", pro příště si ho zapamatuje a používá ho.)

Stejně jako u modulů, i u balíčků platí: s konstrukcí "from ... import *"zacházejte obezřetně, následné starosti s nefunkčním a nepřehledným kódem vás propříště vyléčí. Pokuste se jí používat pouze v interaktivních sezeních.

6.4.2 Odkazování se na moduly uvnitř balíčku

Mnohdy se potřebuje jeden modul odkazovat na jiný modul téhož balíčku. Vyjděme z našeho modelového příkladu. Modul surround bude potřebovat nějakou funkci z modulu echo. V tomto případě platí následující: příkaz import se nejprve podívá do aktuálního balíčku a až poté prohledá standardní cestu (určenou proměnnou sys.path). Proto může modul surround jednoduše použít "import echo". Pokud by modul echo nebyl součástí aktuálního balíčku, přišly by na řadu standardní pravidla pro vyhledávání modulu.

Je-li balíček strukturovaný na podřízené balíčky (v modelovém příkladě například balíček Sound), neexistuje žádný způsob, jak se odkazovat na modul rodičovského balíčku, musíme použít jeho plné jméno. Pokud třeba modul Sound.Filters.vocoder potřebuje modul echo balíčku Sound.Effects, musí použít příkaz from Sound.Effects import echo.



Footnotes

...skript.6.1
Termín skript platí všeobecně, používá se u všech interpretovaných jazyků.
... modulu.6.2
Přípona .py je nutná, běhové prostředá jazyka podle něho rozpozná, že soubor je modulem a umožní ho importovat, toto chování lze změnit přepsáním interní funkce __import__
...import:6.3
Je známo, že import je příkaz s největším množstvím různých variací. Zároveň jde o velmi používaný příkaz, proto byste měli dokonale vědet co a jak provádí. Vše o syntaxi tohoto příkazu se dozvíte z dokumentu Python Language Reference.
...import6.4
Více o výjimkách v kapitole Výjimky
Viz O tomto dokumentu... kde naleznete informace, jak upozornit na případné chyby.