6. Moduly¶
Po ukončení a opětovném spuštění interpretu Pythonu se vytvořené definice (funkce a proměnné) ztratí. Delší program je proto vhodnější připravit v textovém editoru a výsledný soubor použít jako vstup interpretu. Tomu se říká vytvoření skriptu. S rostoucí délkou programu jej možná budete chtít kvůli snazší údržbě rozdělit do několika souborů. Také můžete chtít používat užitečnou funkci ve více programech, aniž byste její definici do každého z nich kopírovali.
Python proto umožňuje uložit definice do souboru a používat je ve skriptu nebo v interaktivní instanci interpretu. Takový soubor se nazývá modul; jeho definice lze importovat do jiných modulů nebo do hlavního modulu (souboru proměnných dostupných ve skriptu prováděném na nejvyšší úrovni a v režimu kalkulačky).
Modul je soubor obsahující definice a příkazy Pythonu. Název souboru tvoří název
modulu s příponou .py. Uvnitř modulu je jeho název jako řetězec dostupný
v globální proměnné __name__. Vytvořte například ve svém oblíbeném editoru
v aktuálním adresáři soubor fibo.py s následujícím obsahem:
# Fibonacci numbers module
def fib(n):
"""Write Fibonacci series up to n."""
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
def fib2(n):
"""Return Fibonacci series up to n."""
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
Nyní spusťte interpret Pythonu a importujte modul následujícím příkazem:
>>> import fibo
Tím se názvy funkcí definovaných v fibo nepřidají přímo do aktuálního
jmenného prostoru (podrobnosti viz Obory platnosti a jmenné prostory v Pythonu);
přidá se do něj pouze název modulu fibo. Přes název modulu lze přistupovat
k funkcím:
>>> fibo.fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
Chcete-li funkci používat často, můžete ji přiřadit lokálnímu názvu:
>>> fib = fibo.fib
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
6.1. Více o modulech¶
Modul může kromě definic funkcí obsahovat i proveditelné příkazy. Ty slouží k inicializaci modulu a provedou se pouze poprvé, kdy se název modulu objeví v příkazu importu. [1] (Provedou se také tehdy, je-li soubor spuštěn jako skript.)
Každý modul má vlastní soukromý jmenný prostor, který všechny funkce definované
v modulu používají jako globální. Autor modulu proto může používat globální
proměnné bez obav z náhodných kolizí s globálními proměnnými uživatele. Pokud
víte, co děláte, můžete ke globálním proměnným modulu přistupovat zápisem
modname.itemname, stejně jako k jeho funkcím.
Moduly mohou importovat jiné moduly. Je zvykem, nikoli povinností, umístit
všechny příkazy import na začátek modulu či skriptu. Názvy modulů
importované na nejvyšší úrovni (mimo funkce a třídy) se přidají do globálního
jmenného prostoru modulu.
Varianta příkazu import importuje názvy z modulu přímo do jmenného
prostoru importujícího modulu. Například:
>>> from fibo import fib, fib2
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Název modulu, z něhož se importuje, se tím do lokálního jmenného prostoru
nezavede (v příkladu tedy není definováno fibo).
Existuje dokonce varianta importující všechny názvy definované modulem:
>>> from fibo import *
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Ta importuje všechny názvy kromě názvů začínajících podtržítkem (_).
Programátoři v Pythonu ji většinou nepoužívají, protože do interpretu zavádí
neznámou množinu názvů a může skrýt již definované položky.
Import * z modulu nebo balíčku se obecně nedoporučuje, protože často vede
k obtížně čitelnému kódu. V interaktivní relaci jej však lze použít pro úsporu
psaní.
Následuje-li za názvem modulu as, naváže se název uvedený za
as přímo na importovaný modul.
>>> import fibo as fib
>>> fib.fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Ve výsledku se modul importuje stejně jako pomocí import fibo, pouze je
dostupný pod názvem fib.
Obdobně lze as použít také společně s from:
>>> from fibo import fib as fibonacci
>>> fibonacci(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Poznámka
Z důvodu efektivity se každý modul v jedné relaci interpretu importuje pouze
jednou. Po změně modulů proto musíte interpret restartovat; chcete-li
interaktivně testovat pouze jeden modul, použijte importlib.reload(),
například import importlib; importlib.reload(modulename).
6.1.1. Spouštění modulů jako skriptů¶
Spustíte-li modul Pythonu pomocí
python fibo.py <arguments>
provede se kód modulu stejně jako při importu, ale __name__ bude nastaveno
na "__main__". Přidáním následujícího kódu na konec modulu:
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
lze proto soubor používat jako skript i importovatelný modul, protože kód zpracovávající příkazový řádek se spustí pouze tehdy, je-li modul proveden jako „hlavní“ soubor:
$ python fibo.py 50
0 1 1 2 3 5 8 13 21 34
Při importu modulu se kód nespustí:
>>> import fibo
>>>
Tento postup se často používá k vytvoření pohodlného uživatelského rozhraní modulu nebo k testování (spuštění modulu jako skriptu provede sadu testů).
6.1.2. Vyhledávací cesta modulů¶
Při importu modulu spam interpret nejprve hledá vestavěný modul tohoto
názvu. Jejich názvy uvádí sys.builtin_module_names. Pokud jej nenajde,
hledá soubor spam.py v adresářích z proměnné sys.path.
sys.path se inicializuje z těchto umístění:
Adresář obsahující vstupní skript (nebo aktuální adresář, není-li zadán soubor).
PYTHONPATH(seznam názvů adresářů se stejnou syntaxí jako shellová proměnnáPATH).Výchozí hodnota závislá na instalaci (podle konvence zahrnuje adresář
site-packageszpracovávaný modulemsite).
Další podrobnosti obsahuje The initialization of the sys.path module search path.
Poznámka
Na souborových systémech podporujících symbolické odkazy se adresář obsahující vstupní skript určí až po následování odkazu. Adresář obsahující symbolický odkaz se tedy do vyhledávací cesty modulů nepřidá.
Po inicializaci mohou programy v Pythonu sys.path měnit. Adresář
obsahující spuštěný skript se umístí na začátek vyhledávací cesty před cestu ke
standardní knihovně. Skripty z tohoto adresáře se proto načtou namísto stejně
pojmenovaných modulů z knihovny. Není-li nahrazení záměrné, jde o chybu. Více
informací obsahuje Standardní moduly.
6.1.3. „Kompilované“ soubory Pythonu¶
Pro urychlení načítání ukládá Python kompilovanou verzi každého modulu do
mezipaměti v adresáři __pycache__ pod názvem
module.version.pyc. Verze kóduje formát kompilovaného souboru a obvykle
obsahuje číslo verze Pythonu. V CPythonu 3.3 by se například zkompilovaný
spam.py uložil jako __pycache__/spam.cpython-33.pyc. Tato konvence
umožňuje souběžnou existenci modulů z různých vydání a verzí Pythonu.
Python porovnává datum změny zdrojového souboru s kompilovanou verzí a zjišťuje, zda není zastaralá a nepotřebuje znovu zkompilovat. Proces je zcela automatický. Kompilované moduly jsou navíc nezávislé na platformě, takže lze tutéž knihovnu sdílet mezi systémy s různými architekturami.
Python mezipaměť nekontroluje ve dvou případech. Modul načtený přímo z příkazového řádku vždy znovu zkompiluje a výsledek neuloží. Mezipaměť také nekontroluje, pokud neexistuje zdrojový modul. Pro distribuci bez zdrojů (pouze kompilovanou) musí být kompilovaný modul ve zdrojovém adresáři a zdrojový modul nesmí existovat.
Několik tipů pro zkušené uživatele:
Přepínači
-Oa-OOpříkazu Python lze zmenšit kompilovaný modul.-Oodstraní příkazy assert,-OOnavíc řetězce __doc__. Některé programy na nich mohou záviset, proto je používejte jen tehdy, víte-li, co děláte. „Optimalizované“ moduly mají značkuopt-a bývají menší. Budoucí vydání mohou účinky optimalizace změnit.Program načtený ze souboru
.pycneběží rychleji než ze souboru.py; rychlejší je pouze jeho načtení.Modul
compilealldokáže vytvořit soubory .pyc pro všechny moduly v adresáři.Podrobnější popis procesu včetně vývojového diagramu rozhodování obsahuje PEP 3147.
6.2. Standardní moduly¶
Python se dodává s knihovnou standardních modulů popsanou v samostatné
Referenční příručce knihovny Pythonu (dále „Referenční příručka knihovny“).
Některé moduly jsou vestavěné do interpretu a zpřístupňují operace, které nejsou
součástí jádra jazyka, ale jsou vestavěny kvůli efektivitě nebo přístupu
k základním prostředkům operačního systému, například systémovým voláním.
Jejich množina závisí na konfiguraci a platformě; modul winreg je třeba
dostupný pouze ve Windows. Zvláštní pozornost si zaslouží sys, vestavěný
v každém interpretu Pythonu. Proměnné sys.ps1 a sys.ps2 určují řetězce
primární a sekundární výzvy:
>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Yuck!')
Yuck!
C>
Tyto dvě proměnné jsou definované pouze v interaktivním režimu interpretu.
Proměnná sys.path je seznam řetězců určující vyhledávací cestu modulů.
Inicializuje se výchozí cestou z proměnné prostředí PYTHONPATH, nebo
vestavěnou výchozí hodnotou, není-li PYTHONPATH nastavena. Můžete ji
měnit běžnými operacemi se seznamem:
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')
6.3. Funkce dir()¶
Vestavěná funkce dir() zjišťuje názvy definované modulem. Vrací seřazený
seznam řetězců:
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__',
'__interactivehook__', '__loader__', '__name__', '__package__', '__spec__',
'__stderr__', '__stdin__', '__stdout__', '__unraisablehook__',
'_clear_type_cache', '_current_frames', '_debugmallocstats', '_framework',
'_getframe', '_git', '_home', '_xoptions', 'abiflags', 'addaudithook',
'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix',
'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing',
'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info',
'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info',
'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth',
'getallocatedblocks', 'getdefaultencoding', 'getdlopenflags',
'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile',
'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval',
'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
'intern', 'is_finalizing', 'last_traceback', 'last_type', 'last_value',
'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks',
'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'pycache_prefix',
'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth', 'setdlopenflags',
'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr',
'stdin', 'stdout', 'thread_info', 'unraisablehook', 'version', 'version_info',
'warnoptions']
Bez argumentů vypíše dir() aktuálně definované názvy:
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
Vypíše všechny druhy názvů: proměnné, moduly, funkce a podobně.
dir() nevypisuje názvy vestavěných funkcí a proměnných. Jejich seznam
získáte ze standardního modulu builtins, v němž jsou definovány:
>>> import builtins
>>> dir(builtins)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException',
'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning',
'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError',
'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning',
'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
'FileExistsError', 'FileNotFoundError', 'FloatingPointError',
'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError',
'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError',
'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError',
'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented',
'NotImplementedError', 'OSError', 'OverflowError',
'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError',
'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning',
'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError',
'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError',
'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__',
'__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs',
'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable',
'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits',
'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit',
'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr',
'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass',
'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview',
'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property',
'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice',
'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars',
'zip']
6.4. Balíčky¶
Balíčky strukturují jmenný prostor modulů Pythonu pomocí „tečkovaných názvů
modulů“. Název A.B například označuje podmodul B v balíčku A.
Stejně jako moduly zbavují své autory starostí s globálními názvy proměnných
jiných modulů, tečkované názvy zbavují autory vícemodulových balíčků, jako jsou
NumPy nebo Pillow, starostí s názvy modulů ostatních balíčků.
Předpokládejme, že chcete navrhnout kolekci modulů („balíček“) pro jednotné
zpracování zvukových souborů a dat. Existuje mnoho formátů zvukových souborů
(obvykle rozpoznaných podle přípony, například .wav, .aiff
a .au), takže možná budete vytvářet a udržovat rostoucí kolekci modulů
pro převody mezi formáty. Se zvukovými daty lze také provádět řadu operací
(míchání, přidání ozvěny, ekvalizace či vytvoření umělého sterea), pro něž
budete psát další moduly. Možná struktura balíčku v hierarchickém souborovém
systému vypadá takto:
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
Při importování balíčku Python prohledává adresáře uvedené v sys.path
a hledá v nich podadresář balíčku.
Soubory __init__.py jsou nezbytné, aby Python považoval adresáře,
které je obsahují, za balíčky (pokud se nepoužívá jmenný balíček, což je poměrně pokročilá funkce). Tím se zabrání tomu,
aby adresáře s běžným názvem, například string, neúmyslně skryly platné
moduly, které se ve vyhledávací cestě modulů nacházejí později. V nejjednodušším
případě může být __init__.py prázdný soubor, může však také provádět
inicializační kód balíčku nebo nastavit proměnnou __all__, která je popsána
později.
Uživatelé balíčku mohou z balíčku importovat jednotlivé moduly, například:
import sound.effects.echo
Tím se načte podmodul sound.effects.echo. Odkazovat na něj je nutné jeho
úplným názvem.
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
Jiný způsob importování podmodulu je:
from sound.effects import echo
Tím se také načte podmodul echo, ale zpřístupní se bez prefixu balíčku,
takže jej lze použít následovně:
echo.echofilter(input, output, delay=0.7, atten=4)
Další možností je importovat požadovanou funkci nebo proměnnou přímo:
from sound.effects.echo import echofilter
Opět se tím načte podmodul echo, tentokrát se však přímo zpřístupní jeho
funkce echofilter():
echofilter(input, output, delay=0.7, atten=4)
Při použití from package import item může být položkou buď podmodul
(nebo podbalíček) daného balíčku, nebo jiný název definovaný v balíčku,
například funkce, třída či proměnná. Příkaz import nejprve ověří, zda je
položka definována v balíčku. Pokud není, předpokládá, že jde o modul, a pokusí
se jej načíst. Jestliže jej nenajde, vyvolá se výjimka ImportError.
Naproti tomu při použití syntaxe jako import item.subitem.subsubitem musí
být každá položka kromě poslední balíčkem. Poslední položkou může být modul nebo
balíček, nikoli však třída, funkce či proměnná definovaná v předchozí položce.
6.4.1. Importování * z balíčku¶
Co se stane, když uživatel napíše from sound.effects import *? Ideálně by
se dalo očekávat, že Python nějak prohledá souborový systém, zjistí, které
podmoduly balíček obsahuje, a všechny je importuje. To by však mohlo trvat
dlouho a importování podmodulů by mohlo mít nežádoucí vedlejší účinky, které
mají nastat pouze při jejich výslovném importování.
Jediným řešením je, aby autor balíčku poskytl jeho explicitní seznam. Příkaz
import používá následující konvenci: pokud kód souboru
__init__.py daného balíčku definuje seznam s názvem __all__, považuje
se tento seznam za seznam názvů modulů, které se mají importovat při použití
from package import *. Při vydání nové verze balíčku musí jeho autor tento
seznam udržovat aktuální. Autoři balíčků se také mohou rozhodnout, že tuto
možnost nebudou podporovat, pokud pro importování * ze svého balíčku nevidí
využití. Soubor sound/effects/__init__.py by například mohl obsahovat
následující kód:
__all__ = ["echo", "surround", "reverse"]
To by znamenalo, že from sound.effects import * importuje tři uvedené
podmoduly balíčku sound.effects.
Mějte na paměti, že podmoduly mohou být zastíněny lokálně definovanými názvy.
Pokud byste například do souboru sound/effects/__init__.py přidali
funkci reverse, příkaz from sound.effects import * by importoval pouze
dva podmoduly echo a surround, ale nikoli podmodul reverse, protože
jej zastiňuje lokálně definovaná funkce reverse:
__all__ = [
"echo", # refers to the 'echo.py' file
"surround", # refers to the 'surround.py' file
"reverse", # !!! refers to the 'reverse' function now !!!
]
def reverse(msg: str): # <-- this name shadows the 'reverse.py' submodule
return msg[::-1] # in the case of a 'from sound.effects import *'
Pokud __all__ není definováno, příkaz from sound.effects import *
neimportuje všechny podmoduly balíčku sound.effects do aktuálního
jmenného prostoru. Pouze zajistí, že byl balíček sound.effects
importován (případně se přitom provede inicializační kód v
__init__.py), a poté importuje všechny názvy definované v balíčku. Patří
sem všechny názvy definované souborem __init__.py (a podmoduly, které
tento soubor výslovně načetl). Patří sem také všechny podmoduly balíčku, které
byly výslovně načteny předchozími příkazy import. Uvažujme tento kód:
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
V tomto příkladu se moduly echo a surround importují do
aktuálního jmenného prostoru, protože jsou v okamžiku provedení příkazu
from...import definovány v balíčku sound.effects. (Funguje to také
tehdy, když je definováno __all__.)
Přestože jsou některé moduly navrženy tak, aby při použití import *
exportovaly pouze názvy odpovídající určitým vzorům, v produkčním kódu se tento
způsob stále považuje za nevhodný postup.
Pamatujte, že na použití from package import specific_submodule není nic
špatného! Ve skutečnosti jde o doporučený zápis, pokud importující modul
nepotřebuje používat stejně pojmenované podmoduly z různých balíčků.
6.4.2. Odkazy uvnitř balíčku¶
Pokud jsou balíčky uspořádány do podbalíčků (jako balíček sound v tomto
příkladu), lze k odkazování na podmoduly souřadných balíčků používat absolutní
importy. Pokud například modul sound.filters.vocoder potřebuje použít
modul echo z balíčku sound.effects, může použít from
sound.effects import echo.
Pomocí tvaru příkazu from module import name lze zapisovat také relativní
importy. Tyto importy používají úvodní tečky k označení aktuálního a nadřazených
balíčků, kterých se relativní import týká. Například v modulu surround
byste mohli použít:
from . import echo
from .. import formats
from ..filters import equalizer
Relativní importy vycházejí z názvu balíčku aktuálního modulu. Protože hlavní modul nemá balíček, moduly určené k použití jako hlavní modul aplikace v Pythonu musí vždy používat absolutní importy.
6.4.3. Balíčky ve více adresářích¶
Balíčky podporují ještě jeden speciální atribut, __path__.
Před provedením kódu v souboru __init__.py balíčku se tento atribut
inicializuje jako sekvence řetězců obsahující název adresáře,
ve kterém se daný soubor nachází. Tuto proměnnou lze upravit; taková změna
ovlivní budoucí vyhledávání modulů a podbalíčků obsažených v balíčku.
Tato funkce není často zapotřebí, lze ji však použít k rozšíření množiny modulů nalezených v balíčku.
Poznámky pod čarou