- Úvod
- Porovnanie Pythona s Javou a C++
- Inštalácia
- Prvé kroky
- Operátory
- Čísla
- Premenné
- Sekvenčné dátove typy
- Reťazce
- Polia
- Riadiace štruktúry, cykly
- Funkcie
- Práca so súbormi
- Python a CGI
- Odkazy
Úvod
Jazyk Python začal vznikať v roku 1989 vo výskumnom ústave v Amsterdame. Pri jeho zrode stál Guido van Rossum. Vznikol premyslený jazyk ktorý je stále vo vývoji.Python ponúka high-level dátové typy, triedy, možnosť práce s modulmi a s chybami sa vyrovná pomocou výnimiek. Tieto špeciality robia z nech optimálny jazyk na rýchly vývoj aplikácií (RAD). Je to programovací jazyk pre minimalistov, presne podľa motta "less is more". Guido pri jeho vývoji stavil na tieto koncepty:
- malý počet výkonných a kombinovateľných základných dátových typov, štandardných funkcií a konštrukcií,
- štrukturovateľnosť pomocou blokov, funkcií, tried a modulov,
- všetky prvky jazyka sú objekty, čo znamená, že sa s nimi manipuluje ako s inými dátami,
- rozšíriteľnosť - pre Python nie je problém "asimilovať" osvedčené prvky z iných jazykov.
V Pythone máme 4 hlavné GUI: Tkinter, wxPython, PyGTK, pyQt. Existuje samozřejmě mnoho dalších (http://wiki.python.org/moin/GuiProgramming). Dajú sa rozdeliť na dve skupiny: pre začiatočníkov Tkinter, wxPython a pre pokročilých PyGTK, pyQt.
Porovnanie Pythona s Javou a C++:
JavaProgramy napísané v jazyku Python bežia obyčajne pomalšie ako Java programy, na druhej strane však vyžadujú menej času na vývoj. Python programy sú typicky 3 až 5 krát kratšie ako ekvivalentné Java programy. Tento rozdiel vyplýva z toho, že Python má zabudované vysoko-úrovňové dátové typy a dynamické pretypovanie. Python programátor sa nemusí zapodievať napr. deklarovaním typov premenných alebo argumentov funkcií.
C++
To isté čo o Jave platí aj o jazyku C++ a naviac: ak Python kód je typicky 3-5 krát kratší ako Java kód, tak pri C++ je to 5-10 krát. Hovorí sa, že jeden Python programátor dokáže dokončiť za dva mesiace to, čo nedokážu dokončiť dvaja C++ programátori za rok.
Interpretované jazyky sú pomalšie ako kompilované?
Interpretované jazyky nie sú kompilované; presnejšie, sú vykonávané okamžite, dávajúc programátorovi výhodu okamžitého obratu. V minulosti, keď servery v spoločnostiach mali menšie výkonnové možnosti ako dnes, čisto interpretované jazyky (ako predošlé verzie Tcl alebo Perl) mali nepatrnú nevýhodu pri výkone niektorých aplikácií. Tá malá nevýhoda zmizla v dnešných komerčných aplikáciách pretože procesory pokročili a jazyky sa zlepšili.
Kto používa Python?
- Infoseek používa Python ako implementáciu a prispôsobenie jazyka
- Yahoo! Používa Python v mnohých z jeho služieb
- NASA používa Python pri systémoch riadenia úloh
- Intel používa Python pri testovaní čipov a matičných dosiek
- Seznam používa Python
Inštalácia
Pre inštaláciu Pythonu potrebujeme stiahnuť aktuálnu verziu pre konkrétny operačný systém z http://python.org/download/Prvé kroky
Prvé kroky Interpreter Pythona spustíte príkazom python, ak ste Python kompilovali, tak /usr/local/bin/python. Malo by sa zobraziť:Python 2.6 (r26:66721, Oct 2 2008, 11:35:03) [MSC v.1500 32 bit (Intel)] on win 32 Type "help", "copyright", "credits" or "license" for more information. >>>a vy si môžete vyskúšať Python ako kalkulačku, prípadne si môžete napísať ultimatívny program pre začiatočníkov:
>>> print 'Hello World!'Interpretra opustíte stlačením EOF na prázdnom riadku (pod Unixmi Ctrl+D, pod Windows Ctrl-Z) alebo príkazmi:
>>> import sys >>> sys.exit()Pythonovské súbory sa ukladajú do súborov s príponou .py. Tie vykonáte príkazom python subor.py. Ak používate nejaký variant operačného systému Unix a nastavíte tomuto súboru execute bit (napr.: chmod 755) a jeho prvý riadok obsahuje #!/usr/bin/env python (nazýva sa magic line), tak ho môžete spustiť priamo (./subor.py). Náš ultimatívny program pre začiatočníkov by v tomto prípade vyzeral takto
#!/usr/bin/env python print 'Hello World!'
Operátory
Unáne aritmetické operátory+x | kladný operand |
-x | negatívny operand |
Bitove operatory
& | AND po bitoch |
| | OR po bitoch |
^ | XOR po bitoch |
~ | komplement k operandu |
>> | shift right |
<< | shift left |
Logicke operatory
and | logický and |
or | logicke or |
not | negácia |
Vyhodnocovanie výrazov sa vykonáva zľava doprava !!!
Binarne aritmeticke operatory
+ | sčítanie |
- | odčítanie |
* | násobenie |
** | umocnenie |
/ | delenie |
// | floor delenie |
% | modulo |
Relacne operatory
< | menší |
> | väčší |
== | rovný |
<= | menší alebo rovný |
>= | väčší alebo rovná |
!=, <> | rôzny |
in | je v sekvenčnom datovom type |
not in | nieje v sekvenčnom datovom type |
is | vracia true, ak oba objekty sú totožné |
is not | vracia true, ak oba objekty sú rôzne |
Všetky relačné operátory majú tú istú prioritu, a ta je nižšia ako u aritmetických operátoroch. Čísla sa porovnávajú aritmeticky, znaky podľa ASCII hodnoty ("a" > "A"). Reťazce sa porovnávajú lexikograficky až do konca jedneho z retazcov alebo do prvého rozdielu medzi porovnávanými retazcami ("abcde" < "abcdef").
Priklad:
(1, 2, 3) < (1, 2, 4) [1, 2, 3] < [1, 2, 4] 'ABC' < 'C' < 'Pascal' < 'Python' (1, 2, 3, 4) < (1, 2, 4) (1, 2) < (1, 2, -1) (1, 2, 3) == (1.0, 2.0, 3.0) (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)!!! porovnáva len rovnaké typy !!!
Od verzie 2.2.0 funguju nasledujuce delimitre. Ich vyznam je obdobny ako v Jave alebo C.
+= | sčítanie |
-= | odčítanie |
*= | násobenie |
**= | umocnenie |
/= | delenie |
//= | floor delenie |
%= | modulo |
&= | AND po bitoch |
|= | OR po bitoch |
^= | XOR po bitoch |
True a False
False hodnoty: None, numerická nula, prázdne sekvenčné dátové typy
True hodnoty: vsšetky ostatné hodnoty.
None
Je to štandardná návratová hodnota funkcií.
Čísla
Jednou z vecí, ktoré môžeme uložiť v premennej, sú čísla. Python rozoznáva tieto druhy čísel:- integers - celé čísla
- plain integers (int) - od -2147483648 do 2147483647
- long integers (long) - sú limitované len pamätou počítača
- floating point numbers (float) - čísla s desatinnou čiarkou
- complex numbers - komplexné čísla
>>> import types >>> s = 100L >>> if type(s) is types.LongType: ... print 'LongInt' LongIntPovolené sú nasledujúce zápisy čísiel:
>>> 100 #celociselny zapis (int) 100 >>> 100L #celociselny zapis (long) 100L >>> 543.2 #desatinny zapis (float) 543.2 >>> 1e2 #exponencialny zapis (float) 100.0 >>> 1e-4 #exponencialny zapis (float) 0.0001 >>> 3 + 2J #zapis komplexneho cisla (3+2j) >>> 0214 #oktanovy zapis (int) 140 >>> 0x28a #hexadecimalny zapis (int) 650Konverzia hodnôt:
>>> a= 5.034 >>> int(a) 5 >>> long(a) 5L >>> float(a) 5.0340000000000001
Python ako kalkulačka
>>> 2+2 4 >>>10*_ 40 >>> (50-5*6)/4 5 >>> 7/3 # vrati dolnu celu cast 2 >>> 7/-3 -3 >>> width = 20 >>> height = 5*9 >>> width * height 900Plná podpora operácií s pohyblivou desatinnou čiarkou
>>> 3 * 3.75 / 1.5 7.5 >>> 7.0 / 2 3.5Podpora práce s komplexnými číslami
>>> 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) >>> a=1.5+0.5j >>> a.real 1.5 >>> a.imag 0.5Operátor delenia
Určite pre jeho zmenu existovalo veľa argumentov pre a proti, pričom vyhralo reálne delenie. Ide v podstate o hru s integer a float operandmi.
Klasické delenie
Keď ho prevádzame s integer hodnotami, potom vynechá desatinné miesta a vráti integer. Keď uvedieme obidve hodnoty (delenú aj deliacu) typu float, vráti nám podiel typu float. Čiže:
>>> 2 / 3 0 >>> 1.0 / 2.0 0.5True delenie
Výsledkom bude vždy skutočný podiel bezohľadu na typ operandov. Je to pomerne veľká zmena, ktorá bude zaradená do verzie Python 3.0, ktorá sa čoskoro objaví. Momentálne je to tak, že true delenie môžeme prevádzať po importovaní from __future__ import division. Potom operátor delenia bude vykonávať len true delenie:
>>> from __future__ import division >>> 1 / 2 0.5 >>> 1.0 / 4.0 0.25Floor delenie
Nový deliaci operátor // vždy vynecháva časť s desatinnými miestami a zaokrúhluje na najbližšie nižšie celé číslo, bezohľadu na numerický typ operandov. Tento operátor začal fungovať vo verzii 2.2 a nie je potrebné ho importovať z modulu __future__.
>>> 1 // 2 0 >>> 3.0 // 2.0 1.0Python podporuje klasicé zátvorkovanie (). Základné funkcie na prácu s číslami sú:
Funkcia | Popis |
---|---|
pow(a,b) | umocní a na b; eqivalent a ** b |
hex(a) | vráti hodnotu decimálneho čísla a v šesnástkovej sústave |
oct(a) | vráti hodnotu decimálneho čísla a v osmičkovej sústave |
long(a) | vráti číslo a v celočíselnom tvare (long), desatinnú časť ignoruje |
int(a) | vráti číslo a v celočíselnom tvare (int), čiže desatinnú časť ignoruje |
float(a) | vráti číslo a v desatinnom tvare |
coerce(a,b) | ak sa dajú obidva argumenty upraviť na ten istý typ, vráti tuple s týmito upravenými argumentami, ináč vráti hodnotu None |
divmod(a,b) | vráti tuple s ((a-a%b)/b, a%b) |
complex(r,i) | vytvorí komplexné číslo z reálnej časti a z imagnárnej časti |
abs(z) | vráti absolútnu hodnotou argumentu z |
z.real, z.imag | vráti reálnu/imaginárnu časť čísla z |
round(x,n=0 | zaokrúhli x na n miest (default 0) |
range(start=0,end,step=1) | vráti pole s číslami od start (default 0) do koniec-1 s krokom (default 1) |
Premenné
Premenné sú základom každého programu. Do premenných môžeme uložiť čísla, reťazce a iné dátové štruktúry. V Pythone sa premenné nedeklarujú a typ premennej je určený automaticky. Identifikátor (meno premennej) môže pozostávať z písmen, čísel a podčiarkovača "_", pričom identifikátory sa nesmú začínať číslami. Pri tvorbe identifikátorov sa vyhýbajte všetkým špeciálnym znakom, ako napr. +, -, -, . atď.,a nesmiete použiť ani tzv. rezervované slová, sú to: access, and, break, class, continue, def, del, elif, else, except, exec, finally, for, from, global, if, import, in, is, lambda, not, or, pass, print, raise, return, try, while. Python má tieto slová rezervované na vlastné účely. Dbajte na to, že Python rozlišuje medzi veľkými a malými písmenami.>>> passe = 3 # bez chyby >>> pass = 3 # chyba, pass je rezerovane slovoV Pythone nie je problém priradiť viacerým premenným jednu hodnotu naraz:
>>> x, y, z = 1, 2, 3 # x=1, y=2, z=3 >>> x = y = z = 0 # x=0, y=0, z=0Komentáre
V Pythone sa komentáre začínajú znakom "#" a končia koncom riadka. Komentár nesmie byť v reťazci.
>>> pocet = 1 # toto je komentar >>> '# toto nie je komentar' '# toto nie je komentar'
Sekvenčné dátove typy
V Pythone sú sekvenčnými dátovymi typmi reťazce, polia a tuple. Pri reťazcoch sa za sekvenciu považujú jednotlivé znaky, pri tuple a poliach sú to jednotlivé prvky. Ku všetkým sekvenčným dátovým typom môžeme pristupovať pomocou indexov alebo slice notácie. Reťazce a tuple sú nemenné, prvky polí sa dajú meniť!Indexovanie, slice notácia
Indexovanie je veľmi mocná zbraň programátorov. Dá sa použiť na všetky sekvenčné dátové typy. Jednoduchým indexovaním pristupujeme k jednotlivým prvkom týchto dátových typov. Slice notácia ("kúsková" notácia :-P), ktorá je podobná tej z jazyka Icon, nám ponúka prácu s indexmi v "množnom čísle", čo znamená, že nepristupujeme len k jedinému prvku, ale rovno k viacerým, vyhradeným dvoma indexmi medzi dvojbodkou. Prvý index ukazuje na miesto, kde s vyznačovaním treba začať, a druhý, kde skončiť. Obidva indexy označujú zľava doprava. Je možné vynechať jeden z týchto indexov. Potom sa označuje od konca/začiatku reťazca (podľa toho, ktorý index vynecháme). V Pythone platí, že indexy sa začínajú nulou. Takisto je možné udať záporné indexy. Pri použití záporných indexov sa zmení smer označovania (sprava doľava). Indexovanie a slice notácia sa najľahšie pochopia na príkladoch:
>>> word[4] # klasika 'A' >>> word[0:2] # slice notacia 'He' >>> word[2:4] 'lp' >>> word[:3] 'Hel' >>> word[2:] 'lpA' >>> word[-1] 'A' >>> word[-2] 'p' >>> word[-2:] 'pA' >>> word[:-2] 'Hel' >>> word[-4:-2] 'el'Schéma indexovania pri použití slice notácie:
0 1 2 3 4 +---+---+---+---+---+ | H | e | l | p | A | +---+---+---+---+---+ -5 -4 -3 -2 -1Základné funkcie pre prácu so sekvenčnými dátovými typmi
Operator | Popis |
---|---|
min(s) | vráti najmensí prvok zo sekvencie s |
max(s) | vráti najväcsí prvok zo sekvencie s |
len(s) | vráti počet prvkov v poli alebo tuple pri použití na retazec jeho dĺžku |
s1 + s2 | spojí sekvenciu s1 so sekvenciou s2 |
seq * x | opakuje sekvenciu seq x-krát, pričom x musí byť prirodzené číslo |
Reťazce
Reťazec vytvoríme tak, že obsah premennej uzatvoríme medzi apostrofy alebo medzi úvodzovky.>>> "retazec" 'retazec' >>> '23+33' '23+33'Ak má byť v samotnom reťazci apostrof "'" alebo úvodzovka """, je nevyhnutné dať pre tento znak backslash "\". Tým utvoríme tzv. escape sekvenciu, pomocou ktorej nahradzujeme znaky, ktoré majú v Pythone rezervovaný význam, ako aj znaky, s ktorých zadávaním by sme mohli mať problémy (napr. ASCII znaky, ktoré sú štandardne neviditeľné, ako medzera, nový riadok,...).
Escape sekvencie
ESC | Popis |
---|---|
\ | prázdna escape sekvencia |
\\ | spätné lomítko (\) |
\' | apostrof (') |
\" | úvodzovka (") |
\a | pípnutie (BEL) |
\b | backspace (BS) |
\e | escape (ESC) |
\t | horizontálny tabulátor (HT) |
\v | vertikálny tabulátor (VT) |
\n | nový riadok (NL) |
\r | návrat vozíka (CR) |
\f | odstránkovanie (FF) |
\0XX ASCII | znak v osmičkovej sústave s hodnotou XX |
\xXX ASCII | znak v šesnástkovej sústave s hodnotou XX |
>>> 'doesn\'t' "doesn't" >>> "doesn't" "doesn't" >>> '"Yes," he said.' '"Yes," he said.' >>> "\"Yes,\" he said.\a" '"Yes," he said.' <> >>> '"Isn\'t," she said.' '"Isn\'t," she said.' >>> print "\x50\x79\x74\x68\x6f\x6e" PythonTu by som chcel spomenut tzv. raw string, ktory sa vytvara takto: r'nejaky_string'. Je vhodny najma na zapis regularnych vyrazov. Nesmie koncint spatnou lomkou.
Funkciu print sme museli použiť, ináč by bol znak nového riadka "\n" vypísaný ako ASCII hodnota. Funkcia print tiež vypúšťa vonkajšie apostrofy alebo úvodzovky, ktoré sú okolo reťazca. Dlhý reťazec, ktorý sa nezmestí na jeden riadok môžeme vytvoriť takto:
hello = "This is a rather long string containing\n\ several lines of text just as you would do in C.\n\ Note that whitespace at the beginning of the line is\ significant." print helloPoužitím spätnej lomky "\" a stlačením klávesu <enter> na konci prvého riadka sme vytvorili prázdnu escape sekvenciu, ktorá je nevyhnutná pre prehľadnosť zdrojového textu. Pomocou nej zapíšeme príkazy, ktoré môžu byť len na jednom riadku, prehľadnejším spôsobom do viacerých riadkov. Existuje šte aj druhá možnosť, ako vytvoriť viacriadkový reťazec,a to pomocou trojice apostrofov '''retazec''' alebo úvodzoviek """retazec""".
Pospájať reťazce je možné uvedením týchto reťazcov vedľa seba, pričom musí ísť len o reťazce, nesmú to byť funkcie, metódy alebo mená premenných! Ak potrebujeme spojiť reťazce s hodnotami uloženými v premenných alebo výstupnými hodnotami funkcií, musíme použiť operátor "+".
>>> 'str' 'ing' 'string' >>> word = 'Help' + 'A' >>> word 'HelpA' >>> '<' + word*5 + '>' '<HelpAHelpAHelpAHelpAHelpA>'Základné funkcie pre prácu s reťazcami
Funkcia | Popis |
---|---|
repr(s) | vráti argument s v apostrofoch |
str(s) | vráti argument s ak je retazec, ak s nie je retazec, tak ho konvertuje na retazec a vráti |
eval(s) | vyhodnotí a vráti výraz v retazci s, opak funkcie repr() |
ord(c) | vráti ASCII hodnotu znaku c |
chr(i) | vráti ASCII znak, ktorému zodpovedá hodnota argumentu i, opak funkcie ord(), 0 <= i < 256 |
Obrátené apostrofy "`" ponúkajú presne to isté, čo funkcia repr() v elegantnejšej a kratšej forme.
>>> 'Slovo \"vlak\" ma ' + `len('vlak')` + ' pismenka' 'slovo "vlak" ma 4 pismenka' >>> ord('p') # ASCII hodnota znaku p 112 >>> chr(112) # teda toto by malo byt p 'p'Formátovaný výstup
>>> print string # ako println >>> print string, # ako printFunkcia print zvláda aj formátovanie výstupu:
>>> print "Sucet cisla %d a cisla %d je: %d" % (2,5,2+5) Sucet cisla 2 a cisla 5 je: 7
%s | reťazec |
---|---|
%x | číslo v šestnástkovom tvare |
%0.3f | reálne císlo zaokruhlené na tri desatiné miesta |
%3d | celé císlo, pričom vľavo sa doplnia medzery tak, aby číslo malo 3 znaky |
%03d | celé číslo, pričom vľavo sa doplnia nuly tak, aby číslo malo 3 znaky |
Znak za % | Popis |
---|---|
* | specifikuje sirku resp. presnost ako integer argument |
- | zarovnaj vlavo |
0 | doplnuje nulami, ak sa zarovnava |
blank | doplnuje medzerami, ak sa zarovnava |
>>> print '%*s' % (10,'text') text >>> print '%-*s%s' % (10,'text','txt') text txt
Polia
Pole vytvoríme priradením hodnôt v hranatých zátvorkách identifikátoru. Jednotlivé prvky poľa sa dajú meniť a dajú sa pridávať nové prvky.>>> a = ['spam', 'eggs', 100, 1234] >>> a ['spam', 'eggs', 100, 1234] >>> 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!'] >>> a ['spam', 'eggs', 100, 1234] >>> a[2] = a[2] + 23 >>> a ['spam', 'eggs', 123, 1234]Použitím slice notácie je možné zmeniť viac prvkov poľa naraz. Ak priraďujeme menej hodnôt, ako je prvkov, na ktoré ukazujeme, budú prebytočno prvky zmazané!
>>> a[0:2] = [1, 12] # zmena prvkov >>> a [1, 12, 123, 1234] >>> a[0:2] = [] # odstranim 2 prvky >>> a [123, 1234] >>> a[1:1] = ['bletch', 'xyzzy'] # vlozim prvky >>> a [123, 'bletch', 'xyzzy', 1234] >>> a[:0] = a # Insert (a copy of) itself at the beginning >>> a [123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]Vnorené polia nie sú pre Python ničím neznámym. V iných jazykoch, napr. C, sa takýmto poliam hovorí viacrozmerné polia:
>>> elop=['python', 'je', 'jazyk'] >>> elop[2]=['skriptovaci', 'jazyk'] #vnorenie dalsieho pola >>> elop ['python', 'je', ['skriptovaci', 'jazyk']] >>> elop[2][1] #pristup pomocou dvojiteho indexovania 'jazyk'List unpacking
List unpacking je extrahovanie prvkov poľa do jednotlivých premenných:
>>> [c1, c2, c3] = elop >>> c1 'python' >>> c2 'je' >>> c3 ['skriptovaci', 'jazyk']Základné funkcie pre prácu s poliami
Funkcia | Popis |
---|---|
a.append(x) | na koniec pola a pripojí objekt x |
a.extend(P) | na koniec pola a pripojí pole P |
a.insert(i, x | na pozíciu (index) v poli a, danú argumentom i, priradí hodnotu x |
a.remove(x) | prepíse prvý prvok pola a s hodnotou x |
a.pop(i) | zmaze a vráti prvok pola a z pozície i; pri nezadaní argumentu, zmaze a vráti posledný prvok pola |
a.index(x) | vráti index prvého prvku s hodnotou x v poli a, v prípade, ze ziadny prvok pola nemá hodnotu x, vráti chybu |
a.count(x) | vráti, info o tom, kolkokrát sa nachádza prvok s hodnotou x v poli a |
a.sort() | zoradí prvky pola a podla abecedy |
a.reverse() | no comment :-) |
list(sekvencia) | vráti pole, ktorého prvky sú prebraté zo sekvencie |
del a[x] | zmaze prvok pola a s indexom x, dá sa pouzit aj so slice notáciou a môze zmazávat celé premenné |
Tieto funkcie môžeme využiť napríklad takto:
Pole ako zásobník
>>> stack = [3, 4, 5] >>> stack.append(6) >>> stack.append(7) >>> stack [3, 4, 5, 6, 7] >>> stack.pop() 7 >>> stack [3, 4, 5, 6] >>> stack.pop() 6 >>> stack.pop() 5 >>> stack [3, 4]Pole ako rad
>>> queue = ["Eric", "John", "Michael"] >>> queue.append("Terry") # Terry arrives >>> queue.append("Graham") # Graham arrives >>> queue.pop(0) 'Eric' >>> queue.pop(0) 'John' >>> queue ['Michael', 'Terry', 'Graham']List comprehension
Je to špecialitka, ktorá bola pridaná až vo verzii 2.0. Umožňuje prehľadnejšie pracovať s prvkami poľa (pretože odpadá potreba používať funkcie ako map(), filter() a/alebo lambda).
List comprehension pozostáva z výrazu, ktorý začína for klauzulou, za ktorou nasleduje nula alebo viac for alebo if klauzul.
>>> vec = [2,4,6] >>> [3*x for x in vec] [6, 12, 18] >>> [3*x for x in vec if x > 3] [12, 18] >>> [3*x for x in vec if x < 2] [] >>> [{x: x**2} for x in vec] [{2: 4}, {4: 16}, {6: 36}] >>> [[x,x**2] for x in vec] [[2, 4], [4, 16], [6, 36]] >>> [(x, x**2) for x in vec] [(2, 4), (4, 16), (6, 36)] >>> vec1 = [2, 4, 6] >>> vec2 = [4, 3, -9] >>> [x*y for x in vec1 for y in vec2] [8, 6, -18, 16, 12, -36, 24, 18, -54] >>> [x+y for x in vec1 for y in vec2] [6, 5, -7, 8, 7, -5, 10, 9, -3] >>> [vec1[i]*vec2[i] for i in range(len(vec1))] [8, 12, -54]
Riadiace štruktúry, cykly
Príkaz ifif_stmt ::= "if" expression ":" suite ("elif" expression ":" suite )* ["else" ":" suite]Vykoná práve jeden suite podľa toho ktorý z výrazov expression vyhodnotil ako true. Ak sú všetky výrazy false, tak výkona suite, ktorý je v klauzule else, ak je uvedený.
Príklad:
>>> x = int(raw_input("Please enter an integer: ")) >>> if x < 0: ... x = 0 ... print 'Negative changed to zero' ... elif x == 0: ... print 'Zero' ... elif x == 1: ... print 'Single' ... else: ... print 'More'Príkaz while
while_stmt ::= "while" expression ":" suite ["else" ":" suite]Ak je expression true, tak sa vykonava prvy suite, a ak nie, tak sa vykona druhy. Break a continue v prvom suite nezaprcini spustenie druhej suite.
>>> while 1: ... try: ... a = int(raw_input('Vloz cele cislo: ')) ... break ... except ValueError: ... print "Prosim, zadajte CELE CISLO!"Príkaz for
Používa sa na iterovanie cez elementy v sekvenčných dátových typoch alebo iných iterovateľných objektoch.
for_stmt ::= "for" target_list "in" expression_list ":" suite ["else" ":" suite]expression_list sa vyhodnotí raz, mal by to byť sekvenčný dátovy typ. suite sa potom vykoná raz pre každý prvok v expression_list-e. Každý prvok sa v kroku priradí do target_list-u. Ak sa vyčerpali všetky prvky, vykoná sa suite v else klauzuje, ak je uvedená.
Príklad:
>>> a = ['cat', 'window', 'defenestrate'] >>> for x in a: ... print x, len(x)break
Ukoncienie for alebo while cyklu.
continue
Ukoncenie iteracie for alebo while cyklu.
pass
Používa sa ak si syntax vyžaduje príkaz pričom necchceme, aby sa niečo vykonalo.
>>> while 1: ... pass # pocka na prerusenie z klavesnice ... # po stlaceni CTRL+C sa to ukonci tymto: Traceback (most recent call last): File "", line 1, in ? KeyboardInterrupt
Funkcie
funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite parameter_list ::= (defparameter ",")* ("*" identifier [, "**" identifier] | "**" identifier | defparameter [","])Definovanie funkcie
Funkcia sa v Pythone definuje takto:
>>> def function(args): """this is documentation string""" ... # telo funkciePriklad:
def fib(n): a,b=0,1 while b < n: print b, a, b = b, a+bVolanie funkcie
Definovana funkcia v Pythone sa vola nasledovne:
>>> print function.__doc__ # volanie dokumentacneho retazca funkcie this is documentation string >>> function(args)Priklad:
>>> fib >>> f = fib >>> f(100) 1 1 2 3 5 8 13 21 34 55 89Standardne definovana funkcia vracia None. Ak chceme vratit nejaku hodnotu, pouzijeme konstrukciu return <hodnota>. V pripade, ze za return neuvedieme hodnotu, ktora sa ma vratit, vracia None. Funkcie su volane hodnotou.
>>> def fib2(n): ... result = [] ... a, b = 0, 1 ... while b < n: ... result.append(b) # eq result = result + [b] ... a, b = b, a+b ... return resultDefault hodnota
Pri definovani argumenov funkcie mozeme uviest aj default hodnotu. Takyto argument s default hodnotou potom pri volani funkcie mozeme, ale nemusime uviest.
Priklad:
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): while 1: ok = raw_input(prompt) if ok in ('y', 'ye', 'yes'): return 1 if ok in ('n', 'no', 'nop', 'nope'): return 0 retries = retries - 1 if retries < 0: raise IOError, 'refusenik user' print complaintFunkcia s default hodnotou sa vola takto:
ask_ok("Do U really want 2 format C:?", 1, "Yes, please!") ask_ok("Do U really want 2 format C:?", complaint="Yes, please!", retries=1)Default hodnota sa vyhodnocuje iba raz. Argumenty s default hodnotami sa musia uvadzat az za standardnymi argumentami.
Funkcie s premenlivou dlzkou argumentov
Ak chceme definovat funkciu s premenlivym poctom argumentov, tak pred argumentom uvedieme "*". Funkcii preda tuple s hodnotami.
Priklad:
def prem_pocet(*arg): return arg >>> prem_pocet('python','cpp',42,'peter') ('python','cpp',42,'peter')Ak chceme zadavat funkcii argumenty v tvare kluc = hodnota, potom musme pred vstupny argument uvies "**". Funkcia preda asociativne pole so zadanymi hodnotami.
Priklad:
def povolanie(**info): for kluc in info.keys(): print kluc, ' - ', info[kluc] >>> povolanie(Meno='Jozef Mrkvicka', Zamestnanie='nezamestnany') Meno - Jozef Mrkvicka Zamestnanie - nezamestnanyV definicii funkcie sa musia argumenty uvadzat v nasledovnom poradi: standardne argumenty, argumenty "s jednou hviezdickou", argumenty "s dvoma hviezdickami".
Praca so subormi
Pr /vypis suboru/:subor = open("ahoj.txt","r") for line in subor.readlines(): print line subor.close()Pr /kopirovanie suboru/:
subor = open("ahoj.txt","r") kopia = open("ahoj.bak","w") for line in subor.readlines(): kopia.write(line) # od verzie 2.0 funguje nova konvencie # pre zapis do suboru (z dovodu prehladnosti) # print >>> kopia, line print "subor skopirovany" subor.close() kopia.close()Zakladne metody:
Metoda | Popis |
---|---|
close() | zatvori subor; zatvoreny subor sa neda citat ani don zapisovat; viacnasobne volanie tejto metody je dovolene |
flush() | flushne interny buffer |
isatty() | true, ak subor je konektnuty na tty-like device, inac false |
fileno() | vrati file descriptor |
read([size]) | cita najviac size znakov zo suboru (ak je size zadane, inac cita cely subor) vracia retazec, retazec je prazdny ak dosiel po EOF |
readline([size]) | vracia retazec cita jeden cely riadok (znak noveho riadku je v stringu tiez ako '\n'), resp. maximalne size znakov, pocita aj '\n'; vrati '' ak dosiel po EOF |
readlines([sizehint]) | cita az po EOF uzitim readline(), vracia pole stringov |
seek(offset[, whence]) |
nastavi aktualnu poziciu v subor na offset; pocita od referencneho bodu whence
whence 0 - zaciatok suboru 1 - aktualna pozicia (default) 2 - koniec suboru |
tell() | vrati aktualnu poziciu v subore |
truncate([size]) | Truncate the file's size. If the optional size argument present, the file is truncated to (at most) that size. The size defaults to the current position. Availability of this function depends on the operating system version (for example, not all Unix versions support this operation) |
write(str) | zapise str do suboru, vracia None; data sa objavia po uziti metody najskor po vyvolani metody flush() alebo close() |
writelines(sequence) | zapise sekvenciu retazcov do suboru; vracia None; |
closed | boolean indikujuci stav suboru; je read-only |
mode | I/O mod suboru; je read-only; ak bol subor otvoreny metodou open(), vrati druhy argument |
name | ak bol subor otvoreny metodou open(), vrati meno suboru |
file(filename[, mode[, bufsize]]) |
vrati novy objekt subor;
filename - subor, ktory sa ma otvorit mode r - read w - write a - append r+ - otvara subor na citanie a zapis b - otvori subor v binarnom mode, zapisuje sa pred r/w/a ak sa subor filename neda otvorit, vyvola IOError |
open(filename[, mode[, bufsize]]) | je to alias metody file |
>>> f=open('/tmp/workfile', 'r+') >>> f.write('0123456789abcdef') >>> f.seek(5) # Go to the 6th byte in the file >>> f.read(1) '5' >>> f.seek(-3, 2) # Go to the 3rd byte before the end >>> f.read(1) 'd'Priklad /vypise do kazdeho riadka jeho poradove cislo/:
f = open('C:\subor.txt', 'r') g = file('c:\subor.cnt', 'w') c = 0 for l in f.readlines(): c = c+1 print >>> g, `c`+': '+l f.close() g.close()Priklad /zrata pocet riadkov a slov v subore/:
from string import split f = open('C:\subor.txt', 'r') countw, countl = 0 for l in f.readlines(): countl += 1 countw += len(split(l)) f.close() print 'Subor obsahuje '+`countw`+' slov a '+`countl`+' riadkov'Priklad /predchadzajuci program aj s kontrolou pri otvarani suboru/:
from sys import exit from string import split try: f = open('C:\subor.txt', 'r') except IOError: print "Nemohol som otvorit subor..." exit(1) countw, countl = 0 for l in f.readlines(): countl += 1 countw += len(split(l)) f.close() print 'Subor obsahuje '+`countw`+' slov a '+`countl`+' riadkov'(un)pickling
Ak si chcem do suboru odlozit nejaku zlzitejsiu strukturu ako slovnik, zoznam, instancie tried, stava sa to vaznym problemom. Na tento problem existuje modul pickle. Pouziva sa takto:
Nech x je nejaky objekt, f je subor otvoreny na zapis, tak x ulozim do suboru takto:
pickle.dump(x, f) # toto sa vola pickling Opacny proces, tj. nacitanie objektu zo suboru funguje takto: x = pickle.load(f) # toto je unpickling
Python a CGI
form.html<html> <head> <title>python</title> </head> <body> <form action="form.py" method="post"> <div> From: <input type="text" name="from"/><br/> To: <input type="text" name="to"/><br/> Text: <br/><textarea name="text" rows="10" cols="60"></textarea><br/> <input type="submit" value="Posli E-mail (POST)"/> </div> </form> </body> </html>form.py
#!C:\Python22\python.exe import cgi, os, string print 'Content-type: text/html' print argums = cgi.parse(cgi.sys.stdin) #nacitame argumeny !!! zbieram data od POSTu, nie GETu d = {} for x in argums.keys(): d[x] = string.split(argums[x][0], '\r\n') print '<html><body>' print '<b>Mail posiela</b>: %s<br>' % d['from'][0] print '<b>Posleme to na adresu</b>: %s<br>' % d['to'][0] print '<b>Text emailu je</b>:<br>' for x in d['text']: print x,'<br>' print '</body></html>'