Program často potřebuje nějakým způsobem předat uživateli data, která vznikla jeho činností. Existuje mnoho možností, jak získat výstup z programu - data mohou být vytisknuta v čitelné formě na standardní výstup nebo je program může zapsat do souboru a umožnit tak jejich další zpracování.
Na začátku této knihy jsme si probrali dvě možnosti, jak vytisknout nějakou
hodnotu na obrazovku: vyhodnocení výrazu v interaktivním interpretru
a příkaz print. (Třetí možností je použití metody write()
souborového objektu "standardní výstup" na nějž se můžeme odkazovat pomocí
proměnné sys.stdout
. Pro více informací o standardních souborových
objektech nahlédněte do dokumentu Library Reference.)
Pravděpodobně budete chtít větší kontrolu nad formátováním výstupu vašeho
programu než je pouhé vytisknutí hodnot oddělených mezerou. Jsou dvě cesty,
kterými se můžete dát - první je napsat si veškerou obsluhu dat sám za použití
slice konstrukcí a operací spojení. Standardní modul string
obsahuje mnohé užitečné funkce pro zarovnávání řetězců
na určitou šířku sloupce. Druhou možností je použití operátoru %
s řetězcem na místě prvního operandu. Operátor %
interpretuje levý
operand jako formátovací řetězec se syntaxí podobnou C funkci
sprintf() a pravý operand jako seznam argumentů, přičemž vrátí
řetězec odpovídající formátovací operaci.
Zbývá poslední otázka: jak převést nějakou hodnotu na řetězec? Naštěstí Python
má možnost zkonvertovat libovolnou hodnotu na řetězec - předání této hodnoty
jako argument funkci str() nebo repr(). (Můžete také
hodnotu zapsat mezi obrácené apostrofy (``
), což je ekvivalent funkce
repr()).
Funkce str() vrací řetězcovou reprezentaci argumentu, která je určena především pro uživatele, zatímco funkce repr() je navržena pro vytváření takových řetězců, které mohou být zpět načteny samotným interpretrem. Pro objekty, které nelze zapsat v čitelné formě, vrátí funkce str() stejnou hodnotu jako funkce repr(). Mnoho hodnot jako čísla nebo strukturované typy (především seznamy nebo slovíky) jsou reprezentovány stejnou hodnotou za použití obou funkcí. Výjimkou jsou řetězce a čísla v plovoucí řádové čárce, která mají dvě rozdílné reprezentace:
>>> s = 'Ahoj světe.' >>> str(s) 'Ahoj světe.' >>> `s` "'Ahoj světe.'" >>> str(0.1) '0.1' >>> `0.1` '0.10000000000000001' >>> x = 10 * 3.25 >>> y = 200 * 200 >>> s = 'Hodnota x je ' + `x` + ' a y ' + `y` + '...' >>> print s Hodnota x je 32.5 a y 40000... >>> # Obrácené uvozovky je možné použít i s jinými typy: ... p = [x, y] >>> ps = repr(p) >>> ps '[32.5, 40000]' >>> # Konvertování řetězců přidá uvozovky a zpětná lomítka: ... ahoj = 'ahoj světe\n' >>> ahojs = `ahoj` >>> print ahojs 'ahoj světe\n' >>> # Argumentem obrácených uvozovek může být i tuple: ... `x, y, ('spam', 'eggs')` "(32.5, 40000, ('spam', 'eggs'))"
Zde jsou ukázány dva způsoby, jak vypsat tabulku druhých a třetích mocnin:
>>> import string >>> for x in range(1, 11): ... print string.rjust(`x`, 2), string.rjust(`x*x`, 3), ... # Nezapomeňte ukončující čárku na předchozím rádku ... print string.rjust(`x*x*x`, 4) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000 >>> for x in range(1,11): ... print '%2d %3d %4d' % (x, x*x, x*x*x) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000
(Mezery mezi každý sloupec přidal samotný příkaz print, který vždy vloží znak mezery mezi jeho argumenty.)
Tento příklad demonstruje použití funkce string.rjust(), která zarovná řetězec mezerami doprava ve sloupci o zadané šírce. Existují obdobné funkce string.ljust() a string.center(). Tyto funkce nic nevypisují, pouze vrátí nový řetězec. Jestliže jejich vstupní řetězec je delší než požadovaná šířka pole, nedojde k oříznutí řetězce, ale vrátí se nezměněná - to může poničit vaše formátování, ale je to lepší než druhá možnost, která zase vrací chybné výsledky. (Jestliže opravdu vyžadujete oříznutí výsledku, můžete použít slice konstrukci podobnou této: "string.ljust(x, n)[0:n]".)
Modul string nabízí ještě jednu funkci string.zfill(), která doplní číselné řetězce zleva nulami a správně interpretuje znaménka plus a mínus:
>>> import string >>> string.zfill('12', 5) '00012' >>> string.zfill('-3.14', 7) '-003.14' >>> string.zfill('3.14159265359', 5) '3.14159265359'
Operátor %
se používá podobně jako funkce sprintf jazyka C:
>>> import math >>> print 'Hodnota Ludolfova čísla je přibližně %5.3f.' % math.pi Hodnota Ludolfova čísla je přibližně 3.142.
Obsahuje-li formátovací řetězec více formátovacích příkazů, musíte operátoru
%
předat jako pravý operand tuple argumentů podobně jako v tomto
příkladě:
>>> tabulka = {'Adolf': 4127, 'Běta': 4098, 'Cyril': 7678} >>> for jmeno, telefon in tabulka.items(): ... print '%-10s ==> %10d' % (jmeno, telefon) ... Běta ==> 4098 Adolf ==> 4127 Cyril ==> 7678
Většina formátovacích příkazů funguje stejně jako v C. Předáte-li jim chybný
argument, nedostanete core dump jako v C, ale z příkazu se rozšíří výjimka.
Příkaz %s
je volnější: jestliže odpovídající argument není řetězec, je
na něj nejprve převeden pomocí interní funkce str(). Použití
*
jako šírky sloupce nebo přesnosti namísto integeru je rovněž
podporováno, zatímco formátovací příkazy %n
a %p
z jazyka C
není možné používat.
Jestliže máte velice dlouhý formátovací řetězec, který nechcete rozdělovat, může
být lepší odkazovat se na proměnné, které mají být použity podle jejich jména
a ne podle pozice. To umožňuje druhý tvar formátovacího příkazu
%(jméno)formát
:
>>> tabulka = {'Adolf': 4127, 'Běta': 4098, 'Cyril': 8637678} >>> print 'Běta: %(Běta)d; Adolf: %(Adolf)d; Cyril: %(Cyril)d' % tabulka Břéťa: 4098; Adolf: 4127; Cyril: 8637678
Velice užitečná je tato vlastnost ve spojení s interní funkcí vars(), která vrací slovník obsahující všechny lokální proměnné:
>>> ahoj = 'Vítáme Vás' >>> print 'Máme pro vás následující zprávu: %(ahoj)s!' % vars() Máme pro vás následující zprávu: Vítáme Vás!
Funkce open() vrací objekt typu soubor (souborový objekt) a je nejčastěji používána se dvěma argumenty: "open(jméno_souboru, mód)".
>>> f=open('/tmp/workfile', 'w') >>> print f <open file '/tmp/workfile', mode 'w' at 80a0960>
První argument je řetězec obsahující jméno souboru. Druhý argument je další
řetězec složený z několika znaků určujících, jakým způsobem bude se souborem
zacházeno. mód může být 'r'
bude-li soubor používán pouze
pro čtení, 'w'
pouze pro zápis (existuje-li již soubor s tímto jménem,
bude smazán) a 'a'
otevře soubor pro přidávání, takže všechna data
zapsana do souboru jsou automaticky přidána na konec souboru. 'r+'
otevře soubor jak pro čtení, tak pro zápis. Argument mód je nepovinný,
je-li vynechán, předpokládá se 'r'
.
Na systémech Windows a Macintosh přidáním 'b'
za mód dojde k otevření
souboru v binárním módu, takže existují ještě módy jako 'rb'
, 'wb'
a 'r+b'
. Windows rozlišují mezi textovými a binárními soubory; znaky
konce řádku jsou automaticky obsluhovány při čtení nebo zápisu dat. Tato skrytá
konverze souborových dat je dobrá pro textové soubory, ale při zápisu
binárních dat typu JPEG nebo třeba .exe velice překáží. Důsledně proto
dbejte na pužívání binárního módu při čtení a zápisu takových souborů. (Přesné
chování textového módu na OS Macintosh závisí na použité C knihovně).
Všechny příklady v této sekci předpokládají, že jste si již vytvořili souborový
objekt nazvaný f
.
Pro přečtení obsahu souboru zavolejte f.read(počet_bytů)
, který
přečte určité množství dat a vrátí je jako řetězec. počet_bytů je
volitelný číselný argument. Je-li počet_bytů vynecháno nebo záporné
číslo, je přečten a vrácen celý obsah souboru (kontrola, jestli soubor není
několikrát větší než vaše dostupná operační paměť, je již na vás). Jinak je ze
souboru přečteno a vráceno nejvýše počet_bytů bytů. Dosáhlo-li se při
čtení konce souboru, f.read()
vrátí prázdný řetězec (""
).
>>> f.read() 'Toto je obsah celého souboru.\n' >>> f.read() ''
f.readline()
přečte jeden řádek ze souboru, přičemž je znak konce řádku
(\n
) ponechán na konci řetězce a je vynechán pouze na posledním řádku
souboru pokud soubor nekončí na novém řádku. Díky tomu je návratová hodnota
jednoznačná - vrátí-li f.readline()
prázdný řetězec, pak bylo dosaženo
konce souboru, zatímco prázdná řádka je reprezentována řetězcem obsahujícím
pouhý znak konce řádku ('\n'
).
>>> f.readline() 'Toto je první řádka souboru.\n' >>> f.readline() 'Druhá řádka souboru\n' >>> f.readline() ''
f.readlines()
vrátí seznam obsahující všechny řádky v souboru.
Předáte-li jí ještě volitelný číselný argument, pak se přečte tolik bytů plus
ještě pár pro dokončení řádku a vrátí se seznam z nich vytvořený. Tato metoda
se se používá nejčastěji pro efektivní čtení velkých souborů řádek po řádku
aniž by program musel mít načten celý soubor v paměti.
>>> f.readlines() ['Toto je první řádka souboru.\n', 'Druhá řádka souboru\n']
f.write(řetězec)
zapíše obsah řetězce řetězec do souboru.
Metoda vždy vrací None
.
>>> f.write('Zkouška mikrofonu - 1 ... 2 ... 3\n')
f.tell()
vrátí celé číslo představující aktuální pozici v souboru
měřenou od začátku souboru. Pro změnu této pozice použijte metodu
"f.seek(offset, odkud)". Nová pozice je vypočtena
připočtením offset k referenčnímu bodu, který je určen argumentem
odkud. Při použití hodnoty 0 je referenčním bodem počátek souboru,
1 znamená aktuální pozici a 2 určuje konec souboru. odkud může být
také vynechán, v tomto případě je použita jeho implicitní hodnota 0:
>>> f=open('/tmp/workfile', 'r+') >>> f.write('0123456789abcdef') >>> f.seek(5) # Jdi na šestý byte v souboru >>> f.read(1) '5' >>> f.seek(-3, 2) # Jdi na 3 byte před koncem souboru >>> f.read(1) 'd'
Jestliže již se souborem nehodláte pracovat, zavolejte f.close() pro
uzavření souboru a uvolnění všech systémových prostředků vyhrazených pro tento
soubor. Po zavolání f.close()
automaticky zhavaruje každý pokus
o přístup k tomuto objektu:
>>> f.close() >>> f.read() Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: I/O operation on closed file
Souborové objekty mají ještě další metody jako isatty() a truncate(), které jsou ale zřídka používané. Pro jejich popis proto prosím nahlédněte do dokumentu Library Reference.
Řetězce mohou být jednoduše čteny a zapisovány do souboru. Čísla potřebují
trochu více péče, protože metoda read() vrací pouze řetězce, které
mohou být předány funkcím jako string.atoi(), která vezme řetězec
jako '123'
a vrátí jeho číselnou hodnotu 123
. Když budete chtít
zapisovat komplexnější datové typy jako seznamy, slovníky nebo instance tříd,
pak se věci stanou ještě složitějšími.
Než aby museli uživatelé neustále psát a ladit kód pro ukládání složitějších datových typů, nabízí Python standardní modul nazývaný pickle. Toto je úžasný modul, který umí zkonvertovat většinu objektů jazyka Python (včetně některých forem kódu!) na řetězcovou reprezentaci. Tento proces se nazývá pickling. Rekonstrukce objektu z řetězce se překvapivě jmenuje unpickling. Mezi pickling a unpickling může být řetězcová reprezentace objektu uložena do souboru nebo třeba zaslána po sítí vzdálenému počítači.
Jestliže máte objekt x
a souborový objekt f
otevřený pro zápis,
pak je možné ho jednoduše uložit jedinou řádkou kódu:
pickle.dump(x, f)
Pro načtení objektu zpět použijeme kód (za předpokladu že souborový objekt
f
je otevřen pro čtení):
x = pickle.load(f)
(Existuje více variant používaných při zápisu více objektů nebo nebo při ukládání pickled dat do řetězce. Kompletní dokumentaci modulu pickle získáte v dokumentu Python Library Reference.)
pickle je standardní cestou, jak vytvářet objekty jazyka Python, které mohou být uloženy a znovu použity jiným programem. Pro takové objekty se používá termín perzistentní objekt. Protože je modul pickle široce používán, mnoho autorů, kteří píší rozšíření jazyka Python, dbá na to, aby nové datové typy (jako matice apod.) bylo možné snadno ukládat a načítat zpět právě pomocí modulu pickle.
See About this document... for information on suggesting changes.