Základy jazyka Python
Varování: Tento dokument je zastaralý a nevztahuje se už k aktuální verzi Pythonu. Poohlédněte se po jiném návodu.
Tento dokument je určen pouze jako základní reference jazyka Python pro programátory, pokud s programováním hodláte teprve začít, tak tento dokument není tím pravým místem.
Charakteristiky jazyka
- multiplatformní
- interpretovaný
- procedurální i objektový
- dynamicky typovaný
- zjednodušená syntax
- řada rozšiřovacích modulů
- záleží na bílých znacích
- rozšířitelnost pomocí C++
IDE
Hello world
print "Hello world"
Spouštění kódu
Kód můžeme přímo spustit interpretem:
python zdrojovy_soubor.py
Nebo pomocí shellu tak, že na začátek souboru přidáme řádku:
#!/usr/bin/env python
S následnou změnou atributů a spuštěním:
chmod a+x zdrojovy_soubor.py ./zdrojovy_soubor.py
Proměnné
Deklarace proměnných se v Pythonu realizuje prostým přiřazením konkrétní hodnoty. Typ proměnné se určí automaticky, automaticky se provádí i přetypování. Pozn.: V závorkách je uveden název objektu v Pythonu, který daný typ zapouzdřuje.
Proměnné mohou být vestavěné (built-in), lokální nebo globální. Chceme-li deklarovat nebo zapisovat do globální proměnné, musíme ji v daném bloku označit jako globální, jinak se vytvoří lokální proměnná, která onu globální překryje:
a = 5 # deklarace promenne a def fl(): a = 10 # vytvoreni _lokalni_ promenne funkce print "a: ",a fl() # vypise a: 10 print "a: ",a # vypise a: 5 def fg(): global a # zpristupni globalni promennou a = 10 # priradi globalni promenne hodnotu 10 print "a: ",a fg() # vypise a: 10 print "a: ",a # vypise a: 10
Číselné proměnné
| typ proměnné | deklarace | alternativní deklarace |
|---|---|---|
| celé číslo (int) | a = 0 | a = int(0) |
| dlouhé celé číslo (long) | a = 0L | a = long(0) |
| reálné číslo (float) | a = 3.1416 | a = float(3.1416) |
| komplexní číslo (complex) | a = 1 + 1.15j | a = complex(1, 1.15) |
Řetězce
| typ proměnné | deklarace |
|---|---|
| řetězec (str) | a = "hello" |
| zápis | hodnota proměnné |
|---|---|
| 'hello' | hello |
| "hello" | hello |
| 'let\'s go' | let's go |
| "let's go" | let's go |
| 'object "str"' | object "str" |
| "object \"str\"" | object "str" |
| '"let\'s" go' | let\'s go |
Řetězec lze rozdělit na více řádků pomocí zpětného lomítka, takto (a pozor, na bílých znacích záleží!):
"EU zavedla prostredky \
pro smirovani obcanu."
Hodnota proměnné, které bude přiřazen tento zápis, bude (všimněte si těch dvou mezer navíc):
EU zavedla prostredky pro smirovani obcanu.
Lze použít klasické zástupné konstrukce pro speciální znaky, jako \n pro konec řádky, \t pro tabulátor, \u0000 pro znaky Unikódu, atd.
Seznamy
| typ proměnné | deklarace | alternativní deklarace |
|---|---|---|
| n-tice (tuple) | a = ('a', 1, 'z') | a = () |
| seznam (list) | a = ['a', 1, 'z'] | a = [] |
| slovník (dict) | a = {'a':1, 'b':'z', 'c':2} | a = {} |
Základní rozdíl mezi n-ticí a seznamem je skutečnost, že n-tice je statická proměnná, kterou nelze za běhu měnit (přidávat či odebírat prvky), zatímco seznam je dynamická proměnná, stejně jako slovník, do kterého lze přidávat či naopak odebírat prvky za chodu. U seznamů lze testovat, je-li určitá hodnota jeho součástí velmi jednoduše:
a = (1,2,3,4,5) print 4 in a # vrati True print 9 in a # vrati False
Přetypování
a = 5 b = long(a) print "a je typ ", type(a), " s hodnotou ", a print "b je typ ", type(b), " s hodnotou ", b
Metody proměnných
Metody objektu complex
| metoda | popis |
|---|---|
| real | vrátí reálnou část komplexního čísla |
| imag | vrátí imaginární část komplexního čísla |
| conjugate() | vrátí komplexně sdružené číslo |
Metody objektu str
| metoda | popis |
|---|---|
| capitalize | vrátí kopii řetězce s velkým prvním písmenem |
| center(w[,f]) | vrátí vystředěný řetězec w znaků široký, použije výplň f |
| count(s) | vrátí počet výskytů řetězce s |
| decode([k]) | dekóduje řetězec z kódování k |
| encode([k]) | vrátí zakódovanou verzi řetězce s kódováním k |
| endswith(s) | vrátí true, pokud řetězec končí řetězcem s |
| expandtabs(n) | nahradí tabulátory n-tými mezerami |
| find(s) | vrátí nejnižší pozici, kde je nalezen řetězec s, jinak vrátí -1 |
| index(s) | jako find, ale zahlásí ValueError, pokud nebude řetězec nalezen |
| isalnum | vrátí true, jsou-li v řetězci jen alfanumerické znaky a je neprázdný |
| isaplha | vrátí true, jsou-li v řetězci jen alfabetické znaky a je neprázdný |
| isdigit | vrátí true, jsou-li v řetězci pouze číslice a je neprázdný |
| islower | vrátí true, jsou-li všechna písmena v řetězci malá a je neprázdný |
| isspace | vrátí true, jsou-li v řetězci pouze bílé znaky a je neprázdný |
| istitle | vrátí true, odpovídá-li řetězec pravidlům titulku a je neprázdný |
| isupper | vrátí true, jsou-li všechna písmena v řetězci velká a je neprázdný |
| join() | spojí všechny řetězce předané jako parametr v jeden |
| ljust(w[,f]) | vrátí řetězec zarovnaný vlevo na odstavec se šířkou w a výplní f |
| lower() | vrátí řetězec v malých písmenech |
| lstrip([z]) | vrátí řetězec zleva oříznutý o znaky z nebo o bílé znaky |
| replace(o,n[,p]) | vrátí kopii řetězce s p-krát nahrazenými znaky o za znaky n |
| rfind(s) | vrátí nejvyšší pozici, kde je nalezen řetězec s, jinak vrátí -1 |
| rindex(s) | jako rfind, ale zahlásí ValueError, pokud nebude řetězec nalezen |
| rjust(w[,f]) | jako ljust, ale zarovnání bude vpravo na odstavec |
| rsplit(s[,m]) | vrátí seznam nejvýše m slov v řetězci při použití oddělovače s |
| split(s[,m]) | jako rsplit, ale operaci provádí zleva |
| splitlines([k]) | vrátí seznam řádek v řetězci, i se zalomením řádku, je-li k true |
| startswith(p) | vrátí true, pokud řetězec začíná řetězcem p |
| strip([z]) | ořeže mezery, popřípadě znaky z |
| swapcase | prohodí malá a velká písmena |
| title | vrátí titulkovou verzi řetězce (velké písmeno na začátku slova, ostatní malá |
| translate(t[,z]) | vrátí kopii řetězce ochuzenou o z přeloženou podle t |
| upper | vrátí řetězec ve velkých písmenech |
| zfill(w) | vrátí numerický řetězec s nulami na začátku o velikosti w |
Metody objektu list
| metoda | popis |
|---|---|
| append(x) | přidá x na konec seznamu |
| count(x) | vrátí počet, kolikrát se prvek x v seznamu vyskytuje |
| extend(S) | přidá všechny prvky seznamu S na konec původního seznamu |
| index(x) | vrátí pozici prvního prvku, který odpovídá prvku x |
| insert(i, x) | vloží prvek x na pozici i |
| pop(n) | odstraní n-tý prvek, bez parametru poslední prvek |
| remove(x) | odstraní první prvek, který odpovídá prvku x |
| reverse | obrátí pořadí prvků v seznamu |
| sort | seřadí seznam |
Metody objektu dict
| metoda | popis |
|---|---|
| clear | vyčistí slovník - vymaže všechny jeho prvky |
| copy(S) | vytvoří kopii slovníku S |
| fromkeys(S[, h]) | vytvoří slovník z prvků seznamu S, jimž přiřadí hodnotu h |
| get(k[, x]) | vrátí k-tý prvek slovníku, nebo x, pokud se v něm nenachází |
| has_key(x) | vrátí true, pokud slovník obsahuje prvek x |
| items | kopie párů klíč - hodnota slovníku |
| iteritems | vrátí iterátor párů klíč - hodnota slovníku |
| iterkeys | vrátí iterátor klíčů slovníku |
| itervalues | vrátí iterátor hodnot slovníku |
| keys | kopie klíčů slovníku |
| pop(k[, x]) | vrátí k-tý prvek ve slovníku, jinak x, a prvek k vymaže |
| popitem | odstraní a vrátí pár klíč - hodnota slovníku |
| setdefault(k[, x]) | vrátí k-tý prvek ve slovníku, jinak x, a prvek k nastaví |
| update([b]) | aktualizuje pár klíč - hodnota ve slovníku |
| values | kopie hodnot slovníku |
Operace s proměnnými
Číselné proměnné
Matematické operace
| zápis | operace |
|---|---|
| x + y | součet |
| x - y | rozdíl |
| x * y | násobení |
| x / y | dělení |
| x // y | celočíselné dělení |
| x % y | zbytek po celočíselném dělení |
| -x | negace |
| +x | žádná změna |
| abs(x) | absolutní hodnota |
| x ** y | x na ypsilontou |
Bitové operace
| zápis | operace |
|---|---|
| x | y | bitové OR |
| x ^ y | bitové XOR |
| x & y | bitové AND |
| x << n | bitový posun vlevo o n bitů |
| x >> n | bitový posun vpravo o n bitů |
| ~x | bitová inverze |
Řetězce
| zápis | operace |
|---|---|
| x in s | vrátí true, obsahuje-li proměnná s hodnotu proměnné x |
| x not in s | vrátí false, obsahuje-li proměnná s hodnotu proměnné x |
| s + t | sloučí řetězce |
| s * n | zkopíruje řetězec s n-krát |
| s[i] | vrátí i-tý prvek (písmeno) řetězce s |
| s[i:j] | vrátí všechny prvky počínaje prvkem i, konče prvkem j |
| s[i:j:k] | vrátí všechny prvky počínaje i konče j s krokováním k |
| len(s) | vrátí délku řetězce (v bytech) |
Konstrukce
Bílé znaky
V Pythonu mají bílé znaky (mezery, apod.) klíčový význam, odsazení tu nahrazuje klasické céčkovské složené závorky, a proto existuje obrovský rozdíl mezi:
if a==5: print "Hello" print "Hello"
a mezi
if a==5: print "Hello" print "Hello"
První zmíněná konstrukce vypíše jedno „Hello“ pouze pokud se proměnná a rovná číslu pět, a druhé „Hello“ v každém případě. Druhá konstrukce vypíše „Hello“ dvakrát, ale pouze v případě, že se proměnná a rovná číslu pět.
Konstrukce pass
Python nesnese prázdnou větev v podmínce nebo cyklu. Vždy je nutné, aby daná větev obsahovala alespoň jeden příkaz. Potřebujete-li prázdnou větev, použijte příkaz pass, který je právě k tomu určen. Ukažme si to na příkladu:
if a == 0: # prazdna vetev neni pripustna # tady dojde k chybe else: print 'a je nenulove'
Ale:
if a == 0: pass # vse OK else: print 'a je nenulove'
Komentáře
Python nezná víceřádkové komentáře, pouze jednořádkové počínaje křížkem:
# komentar
Podmínky
Jednoduchá podmínka:
if podminka: prikazy # vsimnete si odsazeni
Složitá podmínka:
if podminka: prikazy elif podminka: # zkracena verze else if prikazy else: prikazy
Příklad:
if len(filename) > 0: print 'String filename is not empty.' elif filename == 'hacker.txt': print 'Hi, Mr. Hacker' elif filename == 'cracker.txt': print 'Hi, Mr. Cracker' else: print 'Hi, someone else'
Operátory podmínek
| tvar | význam |
|---|---|
| a == b | hodnota proměnné a se rovná hodnotě proměnné b |
| a != b | hodnota proměnné a se nerovná hodnotě proměnné b |
| a > b | číslo a je větší než číslo b |
| a < b | číslo a je menší než číslo b |
| a >= b | číslo a je větší nebo rovno číslu b |
| a =< b | číslo a je menší nebo rovno číslu b |
Cykly
for
Cyklus v Pythonu iteruje trošku jinak než v jiných jazycích. Iteruje nad každou hodnotou v seznamu, nikoliv nad sekvencí čísel, a sice takto:
x = ['a', 'h', 'o', 'j'] for a in x: print a
Pokud potřebujeme iterovat klasickým způsobem, sekvencí čísel, použijeme objekt range(pocatecni_hodnota, koncova_hodnota, velikost_skoku), který nám vytvoří seznam hodnot pro iteraci:
for a in range(0,10): print a
Oba přístupy je možné kombinovat:
a = ['Kobyla', 'ma', 'maly', 'bok.'] for i in range(len(a)): print i, a[i]
while
while podminka:
prikazy
Příklad:
a = 0 while a < 50: a += 5
break, continue, else
V cyklech je možné používat klasické C-čkové konstrukce break, continue, dokonce i else:
for n in range(2, 10): for x in range(2, n): if n % x == 0: print n, ' se rovna ', x, '*', n/x break else: # nebyl nalezen nasobek cisla print n, 'je prvocislo'
Funkce
Syntax:
def funkce(parametr): telo_funkce
Příklad:
def iteruj(od, do): for i in range(od, do+1): print i
Funkce s návratovou hodnotou:
def iteruj(od, do): result = [] for i in range(od, do+1): result.append(i) return result
Funkce s implicitní hodnotou:
def iteruj(od=1, do=10): result = [] for i in range(od, do+1): result.append(i) return result
Tady pozor, implicitní hodnota je dynamické proměnné přiřazena pouze při prvním volání funkce, při ostatních zůstává v proměnné původní hodnota a je třeba mírně obcházet. Buď použít statickou proměnnou:
def f(a, L=()): # L je staticky seznam T=list(L) T.append(a) return T
Nebo upravit funkci:
def f(a, L=None): if L is None: L = [] L.append(a) return L
Parametry funkce lze zadávat buď pozičně nebo přiřazením hodnoty (keyword). U prvního způsobu záleží na pořadí, u druhého nikoliv:
def funkce(text, cislo): for i in range(cislo): print text funkce("ahoj", 4) # primo funkce(cislo=4, text='ahoj') # prirazenim hodnoty
Pokud voláme funkci s více parametry, než funkce umožňuje, vyvoláme výjimku. Můžeme však zbývající parametry zapsat do proměnné typu tuple nebo slovník, podle způsobu zadávání parametrů (viz předchozí bod). Nelze však míchat typy parametrů:
def funkce(text, cislo, *seznam, **slovnik): for i in range(cislo): print text print "Seznam promennych navic: ", seznam print "Seznam prirazeni navic: ", slovnik funkce("ahoj", 4, 'a', a='a', 1, 2, b='c') # hodi vyjimku - pozicni parametr za prirazujicim funkce("ahoj", 4, 'a', 1, 2, b='c', a='a')
Proměnné i funkce jsou objekty, a funkce je možné používat na místo proměnných:
def f(promenna, funkce): for i in range(0, promenna+1): print funkce(i) # zavola funkci 'funkce' s parametrem 'i'
Funkce lambda
Lambda je anonymní funkce, konstrukce, která byla převzata z jazyků jako např. Lisp. Problémem je, že tyto funkce nesmí být složité:
f = lambda a, b: a + b print f(3,6) # vytiskne 9
Jelikož funkce jsou objekty, dají se předávat jako proměnné:
def expo(e): return lambda x: x ** e fx = expo(6) print type(fx) # vrati: <type 'function'> print fx(2) # vrati 2^6, tedy: 64
Dokumentace tříd a funkcí
Funkce i třídy lze dokumentovat níže uvedeným způsobem. Doporučuje se na prvním řádku napsat krátký popis, oddělit prázdnou řádkou a doplnit delším popisem:
def nic_nedelej(): """Funkce, ktera nic nedela Ne, takhle funkce opravdu nic nedela. """ pass print nic_nedelej.__doc__ # vypise dokumentaci funkce
Výjimky
Konstrukce pro výjimky je try … except … finally:
while True: try: x = int(raw_input("Zadejte cislo: ")) break except ValueError: print "To nebylo platne cislo."
Výjimku je možné vyvolat:
raise ValueError, 'Nazdar!'
Lze i vytvořit nový typ výjimky:
class MojeVyjimka(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value)
Klauzule finally (provede se, ať už vznikla nebo nevznikla chyba):
try: raise KeyboardInterrupt finally: print 'Sbohem, svete!'
Výjimky se (třeba na rozdíl od Javy) propagují směrem vzhůru automaticky:
a = 'a' print type(a) def fx(x): if type(x) != int: raise ValueError else: print x def fy(y): fx(y) def fz(z=5): fy(z) fz(a)
Moduly
Moduly představují dodatečnou funkcionalitu, jejíž využití je třeba deklarovat příkazem import. Používá se standardní tečka k oddělení jmenných prostorů:
import math print math.cos(30) dir(math) # vypise vsechny funkce modulu math
Nutnost zadávat jmenný prostor odpadne použitím konstrukce:
from math import * print cos(30)
Úvod do funkcí standardních knihoven naleznete zde a zde. Seznam modulů a jejich popis pak zde.
Vlastní modul
Vytvořit vlastní modul není nic těžkého, jelikož v Pythonu může být kterýkoliv program, který vytvoříte, importován jako modul. Nicméně zkusme si to ukázat na příkladu:
Soubor mujModul.py:
""" Muj modul Nic jineho nez demonstrace, jak vytvaret a pouzivat vlastni moduly.""" import sys def myPrint(* toPrint): """ Upravena funkce print Tato funkce je nahradou za tradicni print, na rozdil od ktereho neoddeluje promenne mezerou.""" for i in toPrint: sys.stdout.write(str(i)) def selfDestruct(): """ Funkce ukonci program I kdyz, kdo by takovou funkci pouzil, kdyz je jeji zapis delsi nez sys.exit()... ale budiz.""" sys.exit()
Jiný soubor:
import mujModul mujModul.myPrint("Hello", "World") mujModul.selfDestruct() mujModul.myPrint("Hello", "World")
Práce se soubory
Soubor se otevírá příkazem open, který má dva parametry, a sice název souboru a mód přístupu k souboru, který může být w pro zápis, r pro čtení a a pro append, tedy zápis automaticky na konec souboru. Na MS Windows a Macintoshi se rozlišuje textový a binární soubor, binární soubor musí mít ještě přídomek b, tedy rb, wb, ab, jinak se zpracuje jako textový. Na unixových systémech existuje pouze binární režim, ale pro zachování portability programu je dobré binární přídomky používat.
soubor=open('/tmp/soubor', 'w')
| metoda | popis |
|---|---|
| close | nastaví closed na true, soubor již nebude přístupný pro I/O operace |
| closed | vrátí true, pokud je soubor uzavřen |
| encoding | kódování, které soubor používá |
| fileno | vrátí popisovač souboru v rámci OS |
| flush | vyprázdní cache |
| isatty | vrátí true, pokud je soubor terminál (tty) |
| mode | mód přístupu k souboru |
| name | název souboru |
| next | objekt soubor je svůj vlastní iterátor, operace vrátí novou řádku |
| read([s]) | přečte nejvýše s bytů nebo přečte celý soubor (pozor, paměť!) |
| readline([s]) | vrátí nejvýše s bytů nebo celou řádku, konce řádku ponechá |
| readlines | vrátí seznam řádek souboru |
| seek(o[,w]) | přesune se na o, w=0 absolutně, w=1 relativně, w=2 relativně ke konci |
| softspace | boolean, je-li třeba mezer pro vytištění další hodnoty |
| tell | vrátí aktuální pozici v souboru |
| truncate([s]) | zkrátí soubor na velikost s nebo na 0 bytů |
| write(s) | zapíše řetězec s do souboru (resp. do cache) |
| writelines(s) | zapíše seznam s do souboru |
| xreadlines | zastaralé, totéž jako iter(soubor) nebo for radek in soubor |
Serializace objektů
Objekty je možné ukládat a číst ze souboru pomocí modulu pickle:
soubor=open('/tmp/soubor', 'w') pickle.dump(objekt, soubor) # ulozeni objektu do souboru ... x = pickle.load(f) # nacteni objektu ze souboru
OOP v Pythonu
Všechny třídy v Pythonu jsou veřejné (public) a všechny metody jsou virtuální - zapouzdření tedy záleží na programátorovi. Dědičnost a polymorfismus jsou samozřejmostí. Třídy se vytváří konstrukcí class:
class distribuce: "Linuxova distribuce" def __init__(self, nazev = 'unknown'): self.nazev = nazev def popis(self): print 'Objekt: ', self print 'Nazev: ', self.nazev a = distribuce("Debian GNU/Linux") a.popis() b = distribuce("Mandriva") b.popis()
Dědičnost (i vícenásobná) se realizuje snadno:
class Potomek(Rodic1, Rodic2, Rodic3): def metoda_1 . . def metoda_n
| důležité metody | popis |
|---|---|
| __bases__ | seznam všech předků třídy |
| __doc__ | dokumentace třídy |
| __module__ | modul, ve kterém se třída nachází |
| __name__ | vrátí jméno třídy |
Iterátory a generátory
Teď už víte, že kterýkoliv objekt lze v Pythonu iterovat v cyklu takto:
s = 'ahoj' for i in s: print s
Tuto funkcionalitu mají na starosti iterátory:
s = 'ahoj' s_iterator = iter(s) print it # iterator je objekt print it.next() # vypise "a" print it.next() # vypise "h" print it.next() # vypise "o" print it.next() # vypise "j" print it.next() # vyhodi vyjimku StopIteration
Pythonský iterační protokol vypadá takto:
iter = x.__iter__() # ziskej iterator try: while True: y = iter.next() # ziskej kazdy prvek ... # zpracuj y except StopIteration: pass # iterator dorazil na konec
Postup pro integrování iterátoru do vlastní třídy je:
class Obraceni: def __init__(self, kObraceni): self.kObraceni = kObraceni self.index = len(kObraceni) def __iter__(self): # vraci iterator tridy return self # v tomto pripade je to trida sama def next(self): # treba definovat funkci next() if self.index == 0: raise StopIteration self.index = self.index - 1 return self.data[self.index]
Python však nabízí jednodušší cestu - generátory. Ty slouží ke zjednodušenému vytváření iterátorů. Jsou zapsány jako normální funkce, ale pro návrat hodnot používají yield. Po každém zavolání metody next() bude generátor pokračovat tam, kde přestal (pamatuje si všechna data a hodnoty). Metody __iter__() a next() se vytvoří automaticky.
def obratit(s) for index in range(len(s)-1, -1, -1): yield s[index] for znak in obratit('ahoj'): print znak
Vestavěné konstanty
- True, False - boolovské hodnoty, novinka ve verzi 2.4
- None - obdoba null, prázdný ukazatel, žádná přiřazená hodnota