Tento i následující díly budou věnovány víceméně standardním modulům, které používá skoro každý. Této náplni věnujeme pouze pár dílů a pak přijdou na řadu zajímavější okruhy – třeba práce se sokety, vytváření e-mailů, služby internetu, XML, GUI a ladění.
Funkce pro práci se soubory
Nejprve si probereme práci se soubory na úrovni obsahu. Podobně jako v jiných jazycích je soubor nejprve nutné otevřít a až poté je možné s jeho obsahem manipulovat. Soubor reprezentuje proměnná, pomocí níž se později přistupuje k jeho obsahu. Soubory mohou být otevírány v několika módech. Každý soubor má přiřazen ukazatel, jenž určuje, na kterém místě bude probíhat další čtení nebo zápis, a po ukončení práce se souborem je slušné ho uzavřít.
Všechny tyto postupy určitě znáte z jazyka C. V Pythonu reprezentuje soubor objekt typu „soubor“. Tento objekt získáme zavoláním funkce file(), která přejímá jako argument jméno souboru. Je možné jí předat i mód, v jakém má soubor otevřít (‚r‘ pro čtení, ‚w‘ pro zápis, ‚b‘ binární mód, případně jejich kombinace), mód má stejný význam jako jako u standardní C funkce fopen(). Lze také uvést velikost bufferu pro práci se souborem.
>>> infile = file('source', 'r') >>> outfile = file('target', 'w') >>> while data: ... data = infile.read(1024) ... outfile.write(data) ... >>> infile.close() >>> outfile.close()
Tento příklad jednoduše ukazuje, jak zkopírovat jeden soubor do druhého. V zájmu kompatibility mezi jednotlivými platformami by bylo lepší předpokládat binární soubory a změnit mód přidáním písmena ‚b‘.
Jak si jistě někteří zkušenější všimli, funkce file() je od verze 2.2 upřednostňována před funkcí open(), která má stejné rozhraní a tutéž funkci. Objekt typu soubor nabízí několik metod, jsou to především:
- read() – metoda, která přečte data ze souboru a vrátí je jako řetězec. Je možné jí předat počet bytů, které má přečíst.
- write() – metoda přejímající jeden argument – řetězec, který má zapsat do souboru
- flush() – vyprázdní vyrovnávací paměť používanou pro přístup k souboru standardní C knihovnou
- seek() – přesune ukazatel aktuální pozice v souboru na zadaný offset
- tell() – vrátí offset aktuální pozice ukazatele v souboru od začátku souboru
Veškeré metody, které pracují se soubory při výskytu chyby, vyvolají výjimky IOError. Pro více informací můžete použít dokumentační řetězce těchto a dalších metod, které objekty typu soubor nabízejí.
Pro manipulaci se soubory na úrovni adresářů musíme použít modul os. Ten obsahuje jeden podmodul os.path (doporučuji přečíst zdrojový kód modulu os, dozvíte se, jak vytvořit modul, aniž by existoval jako soubor). Modul os umožňuje, kromě jiného, pracovat s aktuálním adresářem, získávat seznam souborů, vytvářet, přejmenovávat a mazat adresáře a odkazy.
>>> import os >>> os.listdir('/') ['bin', 'dev', 'etc', 'lib', 'mnt', 'opt', 'tmp', 'var', 'usr', 'boot', 'home', 'proc', 'sbin', 'root'] >>> os.mkdir('/tmp/foo') >>> os.symlink('/', '/tmp/foo/root') >>> os.listdir('/tmp/foo/root') ['bin', 'dev', 'etc', 'lib', 'mnt', 'opt', 'tmp', 'var', 'usr', 'boot', 'home', 'proc', 'sbin', 'root']
Název většiny funkcí je shodný jako odpovídající příkazy shellu. Navíc Python nabízí funkce os.makedirs(), os.renames(), os.removedirs(), což jsou ekvivalenty funkcí pro práci s adresáři, které ale podle potřeby vytvářejí mezilehlé adresáře. Ukázkou vám může být následující příklad:
>>> os.makedirs('/tmp/Python/Tutorial/node1') >>> os.renames('/tmp/Python/Tutorial/node1', ... '/tmp/python/node1') >>> os.removedirs('/tmp/python/node1')
Modul os.path je určen pro manipulaci s cestami k souborům. Jedná se o platformově nezávislou implementaci, která zaručuje (při správném používání) funkčnost na všech podporovaných platformách (např. provádí konverzi normálních lomítek na zpětná v systémech DOS a Windows).
Modul os vytváří mimo jiné jednotné rozhraní ke službám operačního systému. Lze pomocí něho například vytvářet nové procesy (funkce os.system(), případně os.fork()), čekat na existující procesy (os.wait()) nebo pracovat s rourami (os.popen()).
Pomocí proměnné os.environ se přistupuje k proměnným prostředí – jedná se o obyčejné asociativní pole, které jako svoje klíče používá jména proměnných prostředí a jehož hodnoty odpovídají hodnotám proměnných, třeba obsah proměnné $HOME získáme jako os.environ[‚HOME‘].
Všechny funkce modulu os v případě chyby vyvolají výjimku OSError. Instance této výjimky má atributy errno a strerror, které reprezentují číslo chyby a její textový popis. Z čísla proměnné zjistíme její popis pomocí funkce os.strerror().
Modul __builtin__
Prvním modulem, který jsme používali, aniž bychom to věděli, je modul __builtin__. Tento modul reprezentuje builtin (interní) prostor jmen, a proto ho není nutné explicitně importovat příkazem import. Nabízí nám množství užitečných funkcí a některé další typy a proměnné.
Mimo jiné nabízí velice užitečné funkce pro práci se sekvencemi – funkce map(), filter() a reduce(). Každá z nich přejímá jako první argument funkci, které je aplikována na jednotlivé prvky sekvencí.
Funkce map() přebírá kromě funkce jednu nebo více sekvencí. Poté projde veškeré prvky sekvence a postupně je předává jako argumenty funkci. Nakonec vrátí seznam, který je vytvořen z jednotlivých návratových hodnot funkce. Je-li jí předáno více sekvencí, jsou odpovídající si prvky předávány zároveň jako tuple těchto prvků. Jednoduchým příkladem může být výraz, který vypočte součet odpovídajících si prvků sekvencí:
>>> prvni = [2, 5, 1] >>> druhy = [3, 6, 8] >>> def secti(a1, a2): ... return a1 + a2 ... >>> map(secti, prvni, druhy) [5, 11, 9]
Namísto funkce secti se častěji používají anonymní lambda funkce. Je-li jedna sekvence kratší než druhá, doplní se na stejnou délku hodnotami None. Zvláštním případem může být zápis, kdy funkce je nahrazena hodnotou None. Pak je totiž vrácen seznam tuple vytvořených z prvků sekvence.
>>> x1 = [1, 1, 2, 3, 5, 8] >>> x2 = [1, 2, 3, 4, 5, 6] >>> map(None, x1, x2) [(1, 1), (1, 2), (2, 3), (3, 4), (5, 5), (8, 6)]
Funkce filter() prochází jí předanou sekvenci a pro jednotlivé prvky volá funkci, která jí byla předána. Je-li návratová hodnota funkce vyhodnocena jako logická jednička, je odpovídající prvek zahrnut do výsledného seznamu:
>>> cisla = range(20) >>> def sude(x): ... return not (x % 2) ... >>> filter(sude, cisla) [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Konečně funkce reduce() nejprve vezme první dva prvky sekvence a pro ně zavolá funkci, pak pro výsledek funkce a další prvek opět zavolá funkci, a tak pokračuje, dokud nevyčerpá všechny prvky sekvence. Konečnou hodnotu poté vrátí:
>>> cisla = range(10) >>> reduce(lambda A, B: A + B, cisla) 45
Výsledkem je jediná hodnota. Funkci je možné předat i počáteční hodnotu. Více se o tomto triu funkcí můžete dočíst v dokumentaci modulu __builtin__.
Interních funkcí je daleko větší počet, než je možné zde uvést, proto jen telegraficky: pro nalezení minimální (maximální) hodnoty prvku nějaké sekvence je zde funkce min() (resp. max()), funkce file() je rovněž funkcí interní, stejně jako funkce len(), str(), dir(), iter(), abs() nebo range().
V modulu __builtin__ najdete i několik hodnot. Předně jsou to hodnoty None a Ellipsis. Zatímco první znamená „žádný“ objekt (obdoba hodnoty null v C) a má hodnotu logické nuly, druhá se používá u rozšířených slice konstrukcí a my se jí zde zabývat nebudeme. Do interního modulu jsou také zavedena jména všech standardních výjimek, takže je možné je ihned odkazovat bez použití tečkové notace.
Modul sys
Tento modul umožňuje přístup k samotnému jádru interpretru. S jeho pomocí je možné získávat informace o prostředí jazyka, o jeho verzi, nastavovat proměnné důležité pro ladění kódu a činit množství dalších věcí.
Informace o poslední výjimce
Nejdůležitější z této skupiny funkcí je funkce sys.exc_info(), která vrací informace o aktuální obsluhované výjimce. Aktuální obsluhovaná výjimka znamená výjimku, pro kterou již byla spuštěna větev except konstrukce try. Tato funkce vrátí tuple ve tvaru (typ, hodnota, traceback) – kde typ je typ výjimky, hodnota je její instance (obsahuje tedy argumenty výjimky) a traceback je interní objekt obsahující výpis posledních volaných funkcí. Jestliže neexistuje žádná aktuální výjimka, vrátí se trojice hodnot None: (None, None, None). Pomocí této funkce lze získat informace o POSLEDNÍ výjimce, nelze takto zjistit nic o žádné z předchozích.
Trojicí proměnných, které se budou velice hodit při ladění zdrojového kódu, jsou proměnné sys.last_type, sys.last_value, sys.last_traceback. Jsou v nich uloženy informace o poslední neobsloužené výjimce, což umožňuje spuštění post-mortem ladění.
Prostředí a platforma
Interpretr umožňuje získat informace o prostředí, v němž byl spuštěn. Název platformy lze získat jako proměnnou sys.platform, pořadí bytů stroje, na němž interpretr běží, obsahuje proměnná sys.byteorder (řetězce ‚big‘ nebo ‚little‘), jméno spustitelného souboru interpretru najdeme v proměnné sys.executable.
Interpretr také poskytuje informace o své verzi – více o proměnných sys.version, sys.version_info a sys.hexversion najdete v dokumentaci jazyka Python.
Modul sys také nabízí dvě proměnné sys.ps1 a sys.ps2, pomocí nichž se nastavuje primární a sekundární výzva (implicitně ‚>>>‘ a ‚…‘).
Implicitní kódování
Jak již víme, Python používá i Unicode řetězce. Aby bylo zřejmé, do jakého kódování je má konvertovat při použití funkce str(), je třeba toto kódování nastavit. Provádí to správce systému úpravou modulu site, kde volá funkci sys.setdefaultencoding(), poté je již tato funkce nepřístupná. Lze pouze získat hodnotu této proměnné pomocí funkce sys.getdefaultencoding().
Moduly
Modul sys také umožňuje zpřístupnit informace o modulech: seznam všech interních modulů (tj. těch, které byly při kompilaci distribuce přilinkovány k interpretru) získáte jako jméno sys.builtin_module_names, aktuální zavedené moduly získáte jako asociativní pole s názvem sys.modules.
Standardní vstupně výstupní proudy
Tyto proudy, které používá interpretr při vstupu a výstupu, můžete najít jako proměnné sys.stdin, sys.stdout, sys.stderr. Umožňují, aby jim programátor přiřadil svůj vlastní objekt typu soubor (nebo libovolný jiný objekt se stejným rozhraním) a všechny příkazy a funkce (print, input(), raw_input()) s nimi budou spolupracovat.
Příště
V příštím dílu se podíváme na zpracování textů v jazyce Python. Povíme si více o Unicode řetězcích a budeme se zabývat regulárními výrazy a modulem re.