![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
V souvislosti s programováním je funkce pevně určené pořadí příkazů, které provádějí požadovanou operaci. Tato operace je popsána v definici funkce. Syntaxe pro definování funkce je tato:
def jmeno_funkce ( zoznam parametrov ): prikazy
Jméno funkce může být libovolné, kromě klíčového slova Pythonu. Seznam parametrů je výčet informací, které musíme funkci poskytnout. Tento výčet může být i prázdný ().
Uvnitř funkce může být libovolný počet příkazů, ale všechny musí být odsazeny od levého okraje. Doporučovány jsou 4 mezery.
Definice funkce je prvním ze složených příkazů, s kterými se postupně seznámíme. Všechy mají společný vzor:
Uvedeme si příklady několika funkcí bez parametrů:
def novy_riadok (): print
Tato funkce se jmenuje novy_riadok. Prázdné závorky udávají, že je bez parametru. Její tělo obsahuje jediný příkaz jehož výstupem je prázdný řádek. (Použitím přikazu print bez argumentu se generuje znak pro prázdný řádek, který překladač vyhodnotí jako povel k posunu o jeden řádek.)
Definování nové funkce nespustí její provádění. K tomu musíme funkci volat. Při volání funkce zadáváme její jméno a výčet hodnot, kterým v tomto případě říkáme argumenty. Ty jsou přiřazeny k definovaným parametrům funkce. Naše první příklady funkcí nemají parametry, tudíž se při jejich volání nezadávají žádné argumenty. Závorky jsou ovšem povinné:
print "First Line" novy_riadok() print "Second Line"Výstupen tohoto programu je:
First Line
Second Line
Mezera mezi řádky je výsledek volání funkce novy_riadok. Kdybychom chtěli více místa mezi řádky, můžeme volat funkci opakovaně.
print "First Line" novy_riadok() novy_riadok() novy_riadok() print "Second Line"
Nebo můžeme napsat funkci nazvanou tri_riadky, která vytiskne tři nové řádky:
def tri_riadky (): novy_riadok() novy_riadok() novy_riadok() print "First Line" tri_riadky() print "Second Line"
Tato funkce obsahuje tři příkazy odsazené o čtyři mezery. Protože další příkaz není odsazen, Python pozná, že ten již není součástí definované funkce.
Měli bychom si zapamatovat:
V této chvíli nemusí být zcela zřejmé, jaký význam má veškeré koptění s funkcemi. Důvodů může být celá řada, ale náš přiklad demonstruje dva:
Zapíšeme-li útržky kódů z předchozích odstavců do jednoho skriptu (test1.py), může celý program vypadat takto:
def novy_riadok (): print def tri_riadky (): novy_riadok novy_riadok novy_riadok print "First Line." tri_riadky() print "Second Line."
V tomto programu jsou dvě definice funkcí: novy_riadok a tri_riadky. Příkazy uvnitř funkce jsou prováděny až poté, co je funkce volána. Samotná definice funkce negeneruje žádný výstup.
Z čehož tedy vyplývá, že funkce musí být vytvořena před tím, než je volána.
Abychom si byli jisti, že funkce je definována před jejím prvním užitím, potřebujeme znát pořadí, ve kterém jsou příkazy prováděny, neboli průběh výpočtu či průběh provádění.
Provádění vždy začíná prvním příkazem programu. Příkazy jsou prováděny jeden za druhým, většinou od shora dolů.
Definice funkcí nemění průběh výpočtu, ale připomeňme si, že příkazy uvnitř definice se provádějí až po volání funkce. I když je to neobvyklé, můžeme definovat funkci uvnitř jiné funkce. V tomto případě není vnitřní funkce provedena dřív, než je volána vnější funkce.
Volání funkce při běhu programu je jako příkaz k objížďce. Místo přechodu k následujícímu příkazu přeskočí průběh k prvnímu řádku volané funkce, provede tam všechny příkazy a vrátí se tam, kde odbočil.
To zní docela prostě, dokud si neuvědomíme, že jedna funkce může volat druhou. Nacházejíce se uvnitř jedné funkce, může mít program přikázáno provést příkaz v jiné funkci. Provádějíc příkaz v oné jiné funkci, může přijít přikaz k přechodu do ještě jiné funkce ... !
Naštěstí si Python důkladně zaznamenává, kudy při provádění programu prochází, takže se vždy správně vrací tam, odkud při volání funkce vyšel a to tak dlouho, dokud nedojde na konec programu.
Jaké je poučení z tohoto skličujícího příběhu? Čteme-li program, nečteme jej nutně shora dolů, nýbrž sledujeme průběh jeho provádění (výpočtu, exekuce).
Většina funkcí musí mít pro své provedení zadány argumenty, to jest hodnoty, s nimiž fce pracuje. Chceme-li například nalézt absolutní hodnotu čísla např. 5, můžeme použít vestavěnou funkci abs(n):
>>> abs (5) 5 >>> abs (-5) 5
V tomto příkladě jsou argumenty funkce abs(n) čísla 5 a -5.
Některé funkce přjímají více než jeden argument. Například vestavěná funkce pow přijímá dva argumenty, základ a mocnitel. Zadané hodnoty jsou uvnitř funkce přiřazeny proměnným s názvem parametry.
>>> pow (2, 3) 8 >>> pow (7, 4) 2401
Jinou funkcí, která přijímá více než jedem argument je vestavěná funkce max, která vrátí největší ze zadaných argumentů.
>>> max (7, 11) 11 >>> max (4, 1, 17, 2, 12) 17 >>> max (3*11, 5**3, 512-9, 1024*0) 503
Nyní si uvedeme příklad uživatelsky definované funkce s argumentem.
def print_twice(bruce): print bruce, bruce
Tato funkce přijímá jeden argument a přiřadí jej k parametru se jménem bruce. Hodnota parametru (v této chvíli nevíme jaká bude) je tištěna dvakrát. Je vhodné, když název parametru naznačuje typ zadávané hodnoty.
V interaktivním rozhraní Pythonu (IRP) naše funkce snadno vyzkoušíme s použitím příkazu import. Mějme definici funkce print_twice uloženou v souboru kap03.py. Pokud tento soubor a program Python jsou ve stejném adresáři, můžeme tuto funkci importovat do otevřeného IRP:
>>> from kap03 import *
>>> print_twice ('Spam')
Spam Spam
>>> print_twice (5)
5 5
>>> print_twice (3.14159)
3.14159 3.14159
Hodnota argumentu (postupně 'Spam', 5, 3.14159) je při volání funkce přiřazována parametru bruce. Funkci lze zadat libovolný tisknutelný typ argumentu. V našem příkladě jsme postupně zadali řetězec, celé číslo a desetinné číslo.
Stejně jako u vestavěných funkcí můžeme i naši fci print_twice zadat výraz jako argument:
>>> print_twice ('Spam' * 4)
SpamSpamSpamSpam SpamSpamSpamSpam
Výraz 'Spam' * 4 je nejprve převeden na tvar SpamSpamSpamSpam, který je potom zadán funkci jako argument.
Stejně jako u matematických funkcí i funkce Pythonu lze skládat, to jest použít výstup z jedné funkce jako argument pro druhou.
>>> print_twice(abs(-7)) 7 7 >>> print_twice(max(3, 1, abs(-11), 7)) 11 11
V prvním příkladu se vypočítané číslo 7 z fce abs(-7) zadá jako argument fci print_twice. Ve druhém příkladě máme dvě úrovně skladby, neboť výsledek z abs(-11) vstoupí do fce max(3, 1, 11, 7) a její výstup 11 je zpracován fcí print_twice.
Jako argument můžeme také použít proměnnou:
>>> michal = 'Male selatko.' >>> print_twice(michal) Male selatko. Male selatko.
Povšimněme si zde jedné důležité věci. Jméno proměnné michal, kterou zadáváme jako argument, nemá nic společného se jménem parametru bruce. Funkce print_twice říká každému bruce.
Vytvoříme-li proměnnou uvnitř funkce, má platnost pouze uvnitř této funkce a mimo ní ji nelze použít. Říkáme, že je to lokální proměnná. Například:
def cat_twice(part1, part2): cat = part1 + part2 print_twice(cat)
Tato funkce přijímá dva argumenty, zřetězí je a posléze je dvakrát vytiskne. Použijeme dva řetězce:
>>> chant1 = "Pie Jesu domine, " >>> chant2 = "Dona eis requiem." >>> cat_twice(chant1, chant2) Pie Jesu domine, Dona eis requiem. Pie Jesu domine, Dona eis requiem.
Proměnná cat je zničena po ukončení funkce cat_twice. Pokusíme-li se ji vytisknout, dostaneme chybové hlášení:
>>> print cat
NameError: name 'cat' is not defined
Parametry jsou také lokální. Mimo funkci print_twice například neexistuje žádné jméno bruce. Pokusíme-li se jej použít, bude si Python stěžovat.
Abychom mohli sledovat, která proměnná je kde použita, bývá užitečné vytvořit si schematické zobrazení zásobníku (stack diagram). Podobně jako u zobrazení vztahů i v zobrazení zásobníku se uvádí hodnota pro každou proměnnou, zde navíc se jménem funkce, ke které proměnná patří.
Každá funkce je reprezentována svým rámcem. Rámec tvoří jméno funkce s přilehlým obdélníkem, ve kterém jsou uvedeny její parametry a proměnné. Schéma zásobníku pro předchozí příklad vypadá takto:

Uspořádání schematu ukazuje průběh provádění. Funkce print_twice byla volána funkcí cat_twice a cat_twice byla volána funkcí __main__, což je speciální jméno pro nejvrchnější funkci. Když vytvoříme proměnnou vně jakékoliv funkce, patří do __main__.
Každý parametr se vztahuje k téže hodnotě jako jeho odpovídající argument. Tudíž part1 má stejnou hodnotu jako chant1, part2 má stejnou hodnotu jako chant2 a bruce má stejnou hodnotu jako cat.
Objeví-li se chyba při volání funkce, vytiskne Python jména všech funkcí, které se na tomto volání podílely; počínaje poslední, konče první zúčastněnou.
Vyzkoušejme si to. Vytvoříme skript se jménem test2.py, který vypadá takto:
def print_twice(bruce): print bruce, bruce print cat def cat_twice(part1, part2): cat = part1 + part2 print_twice(cat) chant1 = "Pie Jesu domine, " chant2 = "Dona eis requim." cat_twice(chant1, chant2)
Do funkce print_twice jsme přidali příkaz print cat, ale tam není proměnná cat definována. Běh skriptu vyvolá takovéto chybové hlášení:
Traceback (innermost last): File "test2.py", line 11, in <module> cat_twice(chant1, chant2) File "test2.py", line 7, in catTwice print_twice(cat) File "test2.py", line 3, in printTwice print cat NameError: global name 'cat' is not defined
Tento seznam funkcí se nazývá zpětný záznam (traceback). Říká nám ve kterém souboru se chyba vyskytla, který řádek a které funkce byly právě prováděny. Také označí číslo řádku na kterém k chybě došlo
Všimněme si podobnosti mezi zpětným záznamem a zobrazením zásobníku, není náhodná.
| |
| |
|
klíčové_slovo_příkazu: příkaz příkaz ... |
| |
| |
| |
|
| Mějme například následující kód ve skriptu test.py: |
def print_thrice(thing): n = 42 s = "A teraz z jineho soudku ..."Nyní si otevřeme IRP (který je ve stejném adresáři jako test.py): |
>>> n
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined
>>> print_thrice("ouch!")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'print_thrice' is not defined
Poté, co importujeme z test.py vše, můžeme vše použít:
|
>>> from test import *
>>> n
42
>>> s
"A teraz z jineho soudku ..."
>>> print_thrice("Yupee!")
Yupee! Yupee! Yupee!
>>>
Všimněme si toho, že jsme do příkazu import nezahrnuli příponu .py.
|
| |
| |
| |
| |
| |
| |
def cat_n_times(s,n): <zde zapiš svůj kód>Ulož skript import_test.py do adresáře, ve kterém máš uložen exe soubor IRP. Spusť IRP a zkus následující:
>>> from import_test import *
>>> cat_n_times('Spam, 7')
SpamSpamSpamSpamSpamSpamSpam
Chodí? Vyzkoušej si funkci i pro jiné argumenty.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |