Ve všech příkladech v této knize, které uvádějí ukázky vzorového sezení je
vstup pro interpretr označen uvedením výzvy (primární ">>
> " a
sekundární "... "). Výstup z programu je uváděn na samotném řádku přesně
tak, jak jej příkaz print vytiskl. Sekundární výzva uvedená na
samostatném řádku znamená prázdný řádek a je použita k ukončení víceřádkového
příkazu.
Mnoho příkladů v této publikaci, přestože jsou určeny pro zápis v interaktivním módu, obsahuje komentáře. Každý komentář v jazyce Python začíná znakem křížek "#" a pokračuje do konce fyzického řádku. Komentář se může objevit jak na začátku řádky, tak může následovat po "bílých znacích" 3.1 nebo kódu. Znak "#" uvedený uvnitř řetězce neznamená komentář, je považován za znak řetězce:
# toto je první komentář SPAM = 1 # a toto je druhý komentář # ... a nyní třetí! STRING = '# Toto není komentář.'
Nyní si vyzkoušíme několik jednoduchých příkazů jazyka Python. Spusťte si
interpretr a počkejte na zobrazení primární výzvy ">>
> ".
Interpretr se chová jako jednoduchý kalkulátor. Můžete zapsat libovolný výraz a
on vypíše jeho hodnotu. Zápis výrazů je jednoduchý: operátory +
,
-
, *
a /
fungují stejně jako v jiných jazycích (například
Pascal nebo C), rovněž můžete používat závorky pro změnu priority výrazů.
Například:
>>> 2+2 4 >>> # Toto je komentář ... 2+2 4 >>> 2+2 # a toto je komentář na stejném řádku jako kód 4 >>> (50-5*6)/4 5 >>> # Dělení celých čísel vrátí celé číslo: ... 7/3 2 >>> 7/-3 -3
Stejně jako v C je znak rovnítko ("=") určen pro přiřazení hodnoty proměnné. Hodnota proměnné po přiřazení již není interaktivním interpretrem vypsána:
>>> vyska = 20 >>> sirka = 5*9 >>> vyska * sirka 900
Hodnota může být přiřazena i více proměnným najednou:
>>> x = y = z = 0 # Vynuluj x, y a z >>> x 0 >>> y 0 >>> z 0
Python plně podporuje operace v plovoucí řádové čárce (tj. desetinná čísla). Operátor pracující s různými typy operandů si nejprve zkonvertuje celá čísla na čísla v plovoucí řádové čárce a následně provede výpočet (obdobné chování možná znáte z jazyka C):
>>> 3 * 3.75 / 1.5 7.5 >>> 7.0 / 2 3.5
Python také plně podporuje komplexní čísla, přičemž imaginární číslo je zapisováno s příponou "j" nebo "J". Komplexní čísla zapisujeme ve tvaru "(Re + Imj)" nebo je můžeme vytvořit pomocí interní funkce "complex(Re, Im)":
>>> 1j * 1J (-1+0j) >>> 1j * complex(0,1) (-1+0j) >>> 3+1j*3 (3+3j) >>> (3+1j)*3 (9+3j) >>> (1+2j)/(1+1j) (1.5+0.5j)
Komplexní čísla jsou vždy reprezentována dvojicí desetinných čísel, reálnou
a imaginární částí. Chceme-li získat velikosti těchto částí čísla z,
použijeme zápisu z.real
a z.imag
:
>>> z=1.5+0.5j >>> z.real 1.5 >>> z.imag 0.5
Poněvadž v matematice neexistuje způsob, jak převést komplexní číslo na reální,
ani Python nedovoluje použití konverzních funkcí float(),
int() a long() s komplexním argumentem. Raději použijte
funkci abs(z)
pro získání absolutní hodnoty komplexního čísla,
nebo zápis z.real
reprezentují reálnou část čísla:
>>> a=3.0+4.0j >>> float(a) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: can't convert complex to float; use e.g. abs(z) >>> a.real 3.0 >>> a.imag 4.0 >>> abs(a) # sqrt(a.real**2 + a.imag**2) 5.0 >>>
Pokud používáte Python jako stolní kalkulátor, pak se můžete velice snadno vrátit k předchozímu výsledku -- ten reprezentuje proměnná _, například:
>>> urok = 12.5 / 100 >>> penize = 100.50 >>> penize * urok 12.5625 >>> penize + _ 113.0625 >>> round(_, 2) 113.06 >>>
Hodnota proměnné _ by nikdy neměla být modifikována uživatelem. Pokud byste jí přiřadili hodnotu, vytvořili byste nezávislou lokální proměnnou se stejným jménem, která by zakryla interní proměnnou s tímto chováním.
Podobně jako s čísly můžete v Python pracovat i s řetězci. Ty mohou být zapsány mnoha způsoby, především je možné je uvodit jak jednoduchými, tak i dvojitými uvozovkami:
>>> 'houby s voctem' 'houby s voctem' >>> 'rock\'n\'roll' "rock'n'roll" >>> "rock'n'roll" "rock'n'roll" >>> '"To je vražda," napsala.' '"To je vražda," napsala.' >>> "\"To je vražda,\" napsala." '"To je vražda," napsala.' >>> '"To je rock\'n\'roll," řekla.' '"To je rock\'n\'roll," řekla.'
Mnohdy programátor potřebuje řetězec, který je rozložen přes více řádků. Dosáhnout toho opět můžeme několika způsoby. První z nich, který se neváže pouze na řetězce, je spojení dvou po sobě jdoucích řádků znakem zpětného lomítka:
hello = 'Toto je dlouhý řetězec obsahující mnoho\n\ řádek textu, stejně jej zapisujete i v C.\n\ "Bílé" znaky na začátku řádku se samozřejmě\ berou v úvahu.' print hello
Nevýhodou tohoto přístupu je nutnost všechny řádky ukončit vložením
znaků \n
. Zpětné lomítko způsobí ignorování následujícího znaku
nového řádku, řetězec tak může pokračovat na dalším řádku, aniž by bylo nutné
ho ukončit uvozovkami. To demonstruje předchozí příklad, jehož výstupem
je tento text:
Toto je dlouhý řetězec obsahující mnoho řádek textu, stejně jej zapisujete i v C. "Bílé" znaky na začátku řádku se samozřejmě berou v úvahu.
Python podporuje i tzv. raw řetězce (cosi jak ryzí, syrové řetězce), u nichž
se řídící (escape) sekvence nepřevádí na odpovídající znaky.3.2. Raw řetězce charakterizuje předpona r. Potom řetězec r'\n'
odpovídá dvěma znakům - zpětnému lomítku a znaku n, kdežto řetězec '\n'
je jediný znak nového řádku:
hello = r'Toto je dlouhý řetězec obsahující mnoho\n\ řádek textu, stejně jej zapisujete i v C.' print hello
Tento příklad vytiskne text:
Toto je dlouhý řetězec obsahující mnoho\n\ řádek textu, stejně jej zapisujete i v C.
Další možností, jak vytvořit víceřádkový řetězec je jeho uzavření mezi
odpovídající pár trojitých uvozovek ("""
nebo '
).
To má tu výhodu, že nemusíme explicitně zapisovat konce řádků, ty bude
řetězec obsahovat přesně tak, jak jsou zapsány ve zdrojovém kódu:
'
'
print """ Použití: nakladač [VOLBY] -h Zobraz tuto zprávu -H hostname Připoj se na tento počítač """
Tato ukázka vytiskne následující výstup:
Použití: nakladač [VOLBY] -h Zobraz tuto zprávu -H hostname Připoj se na tento počítač
Abychom věděli přesnou podobu řetězce, vytiskne jej interpretr stejným způsobem jako jej zapisujeme, přičemž i všechny speciální znaky jsou uvozeny zpětným lomítkem. (Pokud chceme zobrazit "hodnotu" řetězce, tj. to, co skutečně obsahuje, můžeme použít příkaz print popsaný později. Ten řetězec vytiskne bez uvozovek a se všemi speciálními znaky.)
Řetězce můžeme spojovat pomocí operátoru +
, dokonce je lze opakovat
operátorem *
:
>>> slovo = 'Help' + 'A' >>> slovo 'HelpA' >>> '<' + slovo*5 + '>' '<HelpAHelpAHelpAHelpAHelpA>'
Nalezne-li interpretr v kódu dva zápisy řetězců bezprostředně za sebou, spojí
je dohromady jako by mezi nimi ležel operátor +
. První řádek příkladu
mohl být tedy zapsán jako slovo = 'Help' 'A'
. Ale pozor, takto lze
spojovat pouze zápisy řetězců, pro spojení řetězce a výrazu musíme
použít operátor +
!
>>> import string >>> 'str' 'ing' # <- Správně 'string' >>> string.strip('str') + 'ing' # <- Správně 'string' >>> string.strip('str') 'ing' # <- CHYBNĚ!!! File "<stdin>", line 1, in ? string.strip('str') 'ing' ^ SyntaxError: invalid syntax
Řetězce můžeme (podobně jako v jazyce C) indexovat. První znak řetězce pak má index 0. Poněvadž je Python velice uživatelsky přítulný, nekomplikuje život programátora speciálním typem určeným pro jediný znak -- každý znak řetězce je opět řetězec s délkou 1. Na získání podřetězce nepotřebujeme žádné speciální funkce, samotný jazyk (podobně jako jazyk Icon) podporuje indexování subsekvencí3.3. Subsekvenci indexujeme podobně jako jednotlivé znaky, pouze potřebuje dva indexy (začátek a konec subsekvence), které oddělíme dvojtečkou:
>>> slovo[4] 'A' >>> slovo[0:2] 'He' >>> slovo[2:4] 'lp'
Mezi řetězci v C a v Pythonu ale existuje obrovský rozdíl. Řetězce v jazyce
Python nelze měnit. Jde o celkem logický závěr, řetězec 'ahoj'
vždy bude řetězec 'ahoj'
, proč bychom ho tedy měli měnit?3.4. Pokusíme-li se změnit určitou pozici v řetězci, dojde k chybě:
>>> slovo[0] = 'x' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: object doesn't support item assignment >>> slovo[:1] = 'Splat' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: object doesn't support slice assignment
Proto jedinou cestou, jak vytvářet nové řetězce, je jejich kombinování, které je velice jednoduché a přitom efektivní:
>>> 'x' + slovo[1:] 'xelpA' >>> 'Splat' + slovo[4] 'SplatA'
Slice indexy mají ještě další specifické vlastnosti. Vynecháme-li první index, je za něj automaticky dosazena nula (začátek řetězce). Při neuvedení druhého indexu se použije délka řetězce (čili konec řetězce): 3.5.
>>> slovo[:2] # První dva znaky 'He' >>> slovo[2:] # Vše s výjimkou prvních dvou znaků 'lpA'
Kód ve tvaru s[:i] + s[i:]
je samozřejmě vyhodnocen jako s
:
>>> slovo[:2] + slovo[2:] 'HelpA' >>> slovo[:3] + slovo[3:] 'HelpA'
Další vlastností slice indexů je jejich automatické "zarovnávání" na rozměr řetězce. Je-li totiž index použitý ve slice konstrukci příliš velký, je nahrazen délkou řetězce. Podobně -- pokud je dolní index větší než horní, je výsledkem prázdný řetězec:
>>> slovo[1:100] 'elpA' >>> slovo[10:] '' >>> slovo[2:1] ''
Pokud jsou indexy záporná čísla, dojde k počítání od konce řetězce. Názorně to ukazuje následující příklad i s komentáři:
>>> slovo[-1] # Poslední znak 'A' >>> slovo[-2] # Předposlední znak 'p' >>> slovo[-2:] # Poslední dva znaky 'pA' >>> slovo[:-2] # Vše kromě posledních dvou znaků 'Hel'
Pozor ale, -0 je totéž co 0, k žádnému indexování od konce řetězce tím pádem nedojde:
>>> slovo[-0] # (-0 je totéž co 0) 'H'
Záporné indexy při indexaci podřetězců jsou zarovnány na velikost řetězce, proto není chybou, sahají-li indexy mimo řetězec. To platí ale pouze pro slice indexy, indexy, které vystupují samostatně jsou ponechány tak, jak jsou. Pokud je řetězec kratší a index padne mimo něj, dojde k chybě:
>>> slovo[-100:] 'HelpA' >>> slovo[-10] # CHYBNĚ!!! Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: string index out of range
Pokud i přesto, že jsme se podsekvencím tolik věnovali, nechápete, jak jednotlivé znaky a podsekvence z nich složené získat, možná vám přijde vhod následující schema.
Důležité je si zapamatovat, že slice indexy ukazují mezi znaky, přičemž levá hrana prvního znaku má číslo 0 a pravá hrana posledního znaku řetězce o n znacích má index n:
+---+---+---+---+---+ | H | e | l | p | A | +---+---+---+---+---+ 0 1 2 3 4 5 -5 -4 -3 -2 -1
Na prvním řádku jsou uvedeny všechny možné slice-indexy 0...5 v řetězci 'HelpA', na druhém pak odpovídající záporné hodnoty. Řez od i do j je tedy tvořen všemi znaky mezi hranami označenými mezi hranami označenými i a j.
Pokud potřebujete zjistit délku určitého řetězce, jistě využijete interní funkci len():
>>> s = 'supercalifragilisticexpialidociální' >>> len(s) 35
Pro nezáporné slice-indexy je délka řezu rozdílem slice-indexů pokud oba
"padnou" dovnitř řetězce. Například, délka řezu word[1:3]
je 2.
Vydáním Pythonu 2.0 se jazyk dostal mezi skupinku jazyků podporujících Unicode. Od té doby Python umí pracovat s Unicode řetězci (viz http://www.unicode.org/) úplně stejným způsobem jako s obyčejnými řetězci. To umožňuje snadnou integraci Unicode do již existujících aplikací. Dokonce je možné díky konverzním funkcím snadno převádět obyčejné řetězce na Unicode a zpět.
Čím je Unicode tak pokrokové? Především v tom, že každému znaku libovolného jazyka přiřazuje jedinečný index. Tím se liší od dříve používaného schematu, kdy se používalo pouze 256 indexů a několik kódových tabulek, takže jednomu indexu odpovídalo více znaků (každý v jiné tabulce). To vedlo k velkým zmatkům, rovněž bylo nutné respektovat internacionalizaci3.6 programů, což je zajištění správné funkce programu v různých národních prostředích (program akceptuje národní znaky, správně provádí třídění, konverzi řetězců apod.). Unicode proto definuje pouze jedinou kódovou stránku pro všechny jazyky. Program pak zachází se všemi znaky Unicode stejným způsobem a nepotřebuje rozlišovat mezi různými jazyky a kódovými stránkami.
Unicode řetězce můžeme zapisovat přímo ve zdrojovém kódu programu. Pouze před samotný řetězec vložíme prefix u (podobně jako u raw řetězců prefix r):
>>> u'Hello World !' u'Hello World !'
Jak vidíme, Unicode řetězec se bez problémů vytvořil. Že se jedná o Unicode řetězec snadno poznáme podle malého písmena "u" před řetězcem. Chcete-li do řetězce vložit speciální znak, můžete tak učinit díky Unicode-Escape módu. Nejlépe to uvidíte na následující ukázce:
>>> u'Hello\u0020World !' u'Hello World !'
Escape sekvence \u0020
znamená vložení Unicode znaku s hodnotou
0x0020 (znak mezera) na dané místo v řetězci.
Všechny ostatní znaky jsou interpretovány za použití jejich odpovídajících hodnot v kódové stránce Unicode. Jste-li obeznámeni s převodními tabulkami mezi jednotlivými národními kódovými stránkami a kódovou stránkou Unicode, jistě jste si všimli, že prvních 256 znaků Unicode přesně odpovídá všem 256 znakům kódové stránky Latin-1.
I s Unicode řetězci je možné používat raw mód s podobnou funkcí jako raw mód
obyčejných řetězců. Tento mód aktivujeme použitím prefixu ur namísto
standardního u. Python pak začne používat tzv. Raw-Unicode-Escape mód.
V tomto módu Python nahrazuje pouze sekvence typu \uXXXX
a ostatní
(třeba \n
) nechává tak jak jsou:
>>> ur'Hello\u0020World !' u'Hello World !' >>> ur'Hello\\u0020World !' u'Hello\\\\u0020World !'
Výhody raw módu oceníte především potřebujete-li zapsat větší množství zpětných lomítek (např. při zápisu regulérních výrazů).
Nehledě na tyto standardní zápisy nabízí Python ještě celou řadu způsobů, jak Unicode řetězce vytvořit.
Pro konverzi znaků z osmibitového kódování (klasické řetězce) do kódování Unicode můžete použít interní funkci unicode() , která umožňuje přístup ke všem registrovaným kodekům, které dokáží vytvořit Unicode řetězce z řetězce v téměř libovolném kódování (např. Latin-1, ASCII, UTF-8 nebo UTF-16). Implicitní kódování je ASCII. To pro hodnoty znaků používá pouze 7 bitů (proto je možné používat pouze znaky v rozsahu 0 až 127). Při použití rozšířených znaků (např. znaky s diakritikou apod.) dojde k chybě.
Pro převod Unicode řetězce zpět na standardní lze s výhodou použít interní funkci str(). Ta používá implicitní kódování.3.7
>>> u"abc" u'abc' >>> str(u"abc") 'abc' >>> u"äöü" u'\xe4\xf6\xfc' >>> str(u"äöü") Traceback (most recent call last): File "<stdin>", line 1, in ? UnicodeError: ASCII encoding error: ordinal not in range(128)
Chceme-li při konverzi Unicode řetězce na 8bitový specifikovat kódování, v němž má cílový řetězec být, musíme použít metodu encode() Unicodového řetězce. Té předáme jediný argument -- jméno kódování (platí, že všechna jména kódování se píší malými písmeny):
>>> u"äöü".encode('utf-8') '\xc3\xa4\xc3\xb6\xc3\xbc'
Opačnou konverzi umožňuje již zmíněná funkce unicode(), které lze opět předat jediný argument -- jméno kódování, ve kterém je původní osmibitový řetězec. Převodu výše uvedeného výsledku zpět dosáhneme tímto voláním:
>>> unicode('\xc3\xa4\xc3\xb6\xc3\xbc', 'utf-8') u'\xe4\xf6\xfc'
Jazyk Python podporuje i další datové typy. Jde především o tzv. složené datové typy, které slouží k uložení jiných hodnot. Nejuniverzálnější z nich je seznam.
Seznam vznikne, zapíšeme-li výčet libovolných hodnot oddělených čárkou mezi hranaté závorky. Není nutné, aby všechny prvky seznamu měly stejný typ:
>>> a = ['spam', 'eggs', 100, 1234] >>> a ['spam', 'eggs', 100, 1234]
Seznamy podporují, podobně jako řetězce, mnoho dalších operací. Namátkou jmenujme spojování, násobení celým číslem, indexování, operace s podsekvencemi (slice) a další:
>>> a[0] 'spam' >>> a[3] 1234 >>> a[-2] 100 >>> a[1:-1] ['eggs', 100] >>> a[:2] + ['bacon', 2*2] ['spam', 'eggs', 'bacon', 4] >>> 3*a[:3] + ['Boe!'] ['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boe!']
Zásadní rozdíl mezi řetězci a seznamy spočívá v možnosti změny prvků. Zatímco u řetězců to nepřipadá v úvahu -- jde o typ neměnný, seznamy se jí nebrání -- tento typ nazýváme proměnný. Seznam lze změnit pomocí přiřazení nového prvku na určitý index:
>>> a ['spam', 'eggs', 100, 1234] >>> a[2] = a[2] + 23 >>> a ['spam', 'eggs', 123, 1234]
Rovněž lze přiřadit hodnotu určité subsekvenci. Takto dokonce můžeme změnit i počet prvků seznamu:
>>> # Změna prvků: ... a[0:2] = [1, 12] >>> a [1, 12, 123, 1234] >>> # Jejich odstranění: ... a[0:2] = [] >>> a [123, 1234] >>> # Vložení nových: ... a[1:1] = ['bletch', 'xyzzy'] >>> a [123, 'bletch', 'xyzzy', 1234] >>> a[:0] = a # Vložení kopie seznamu do sebe sama >>> a [123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
Podobně jako na řetězce můžeme i na seznamy aplikovat interní funkci len(). Jako její návratovou hodnotu pak obdržíme počet prvků obsažených v seznamu:
>>> len(a) 8
Někdy se může hodit i možnost vytvořit seznam obsahující jiné seznamy, třeba:
>>> q = [2, 3] >>> p = [1, q, 4] >>> len(p) 3 >>> p[1] [2, 3] >>> p[1][0] 2 >>> p[1].append('xtra') # Viz. sekce 5.1 >>> p [1, [2, 3, 'xtra'], 4] >>> q [2, 3, 'xtra']
V posledním uvedeném příkladě si všimněte jedné věci: objekty p[1]
a
q
jsou jeden a týž seznam. Změnou jednoho se změní i druhý. To umožňuje
mechanismus odkazů na objekty. Později se k nim ještě vrátíme, již nyní
ale můžeme prozradit, že se jedná o velice důležitou problematiku a bez její
znalosti Python těžko pochopíte.
Jazyk Python lze samozřejmě použít k daleko komplikovanějším úlohám. Například můžeme vypsat počáteční prvky Fibonacciho rozvoje3.8:
>>> # Fibonacci rozvoj: ... a, b = 0, 1 >>> while b < 10: ... print b ... a, b = b, a+b ... 1 1 2 3 5 8
Tento příklad demonstruje několik pro nás v tuto chvíli nových vlastností:
a
a b
jsou zároveň přiřazeny dvě nové hodnoty.
Na poslední řádce ukázky je tento obrat použit znovu pro získání nové dvojice
čísel.
b < 10
) zůstává pravdivá. Test použitý v tomto případě (b < 10
) je ukázkou jednoduchého
porovnání. Paleta standardních porovnávacích operátoru je shodná s jazykem C:
<
(menší než), >
(větší než), ==
(rovno), <=
(menší
nebo rovno), >=
(větší nebo rovno) a !=
(nerovno). Výsledkem porovnání
je podobně jako v C číslo. Jako podmínku však můžeme použít libovolnou hodnotu.
Jakékoli nenulové číslo znamená pravdivou hodnotu, nula nepravdivou. Podmínkou
může být dokonce i jiný typ než číslo (například libovolná sekvence).
>>> i = 256*256 >>> print 'Hodnota proměnné i je', i Hodnota proměnné i je 65536
Pokud výčet výrazů ukončíte čárkou, nedojde k vložení znaku nového řádku, další příkaz print tedy bude pokračovat na tomtéž řádku.
>>> a, b = 0, 1 >>> while b < 1000: ... print b, ... a, b = b, a+b ... 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 >>>
Jestliže jste ale v interaktivním módu, interpretr před zobrazením další výzvy ukončí předchozí řádek, výzva pak je zobrazena v prvním sloupci terminálu.
\n
- znak nového řádku nebo
\t
- tabulátor
r[n+2] = r[n] + r[n+1]
.
Začíná tudíž čísly 1, 1, 2, 3, 5, 8, 13 atd.: