Další Předchozí Obsah

9. Funkce

9.1 Definice funkce

V Pythonu je samozřejmě možné definovat funkce. Provádí se to příkazem def. Nadefinujme třeba funkci pro sčítání.

def sum(a,b):
        s = a+b
        print '%s+%s=%s' % (a, b, s)
        return s

Tato funkce bere dva parametry a vrací hodnotu. Všimněte si, že nikde se nemusí zadávat, jakého typu mají být parametry a jaký typ hodnoty se bude vracet na výstupu.

Provádění funkce začíná na prvním řádku a končí buď posledním řádkem nebo tím, že Python narazí na příkaz return. (Existuje ještě jedno ukončení a to výjimkou, leč i k tomu se dostaneme. Ale později.). V případě nárazu na return se vypočítá hodnota výrazu za příkazem a vrátí se jako výsledek funkce. Není-li uvedena žádná hodnota, funkce vrátí speciální hodnotu None.

Po definici funkce je možné do promptu napsat print sum(1,2) a Python by měl vypspat ven výsledek 3. Protože v Pythonu není nijak definované co smí být parametrem funkce, je možné funkce volat i jako sum('a', 'bf'). Operátor + funguje i pro řetězce a tak dostaneme správný výsledek.

Funkce začíná existovat provedením příkazu def, její existence končí příkazem del. Po použití del sum nebude po funkci sum ani vidu, ani slechu (přinejmenším do další definice sum).

ADVANCED: Definicí funkce pomocí příkazu def se vytvoří objekt typu funkce. Všechny objekty typu funkce spustitelné (anglicky callable), proto je možné je volat.

9.2 Docstringy

Začněmež definicí funkce:

def rindex(s,c):
        """fact(s,c)
        vrací pozici posledního znaku 'c' v řetězci 's'"""
        copy = s[:]     # vytvoříme kopii
        copy.reverse()  # otočíme ji
        return len(s)-copy.index(c)

Komentáře za mřížkami jsou vcelku obvyklá záležitost. Co je méně obvyklé je řetězec těsně za příkazem def. Těmto řetězcům se v angličtině říká docstring, v češtině svůj název (zatím) nemají a poskytují programátorům v Pythonu možnost podat informace o příslušném objektu. Tyto řetězce narozdíl od komentářů zůstávají i ve zkompilovaném bytekódu (nepožádáme-li o jejich vyřezání).

Přesnější pravidlo: Je-li prvním symbolem za definicí funkce volně ložený řetězec, je považován za docstring a je s ním podle toho nakládáno.

Každý objekt, který má vlastní docstring, má definován atribut __doc__, v němž se docstring nachází. Vypsat se dá například následovně:

>>> print rindex.__doc__
fact(s,c)
        vrací pozici posledního znaku 'c' v řetězci 's'

Python má k dispozici prostředky, jak zjistit docstringy hromadně z již zkompilovaného bytekódu. Dostaneme-li tedy od kolegy bytekód, ke kterému nám nedal zdrojový text, máme možnost jak zjistit informace o volání příslušných funkcí (za předpokladu, že kolega nebyl vtipálek a nepsal nesmyslné docstringy).

9.3 Keyword calling

Uvažujme následující funkci, která zpracovává větší než malé množství parametrů:

def vypis(pocet, kod, nazev, cena_za_kus, dph):
        ...
        <v tomto místě se provádí zpracování a výpis>
        ...

Je-li funkce definovaná někde na jednom konci programu a voláme-li ji z jiného konce, dá se vcelku jednoduše zapomenout (a následně poplést) pořadí parametrů. V takových případech je možné (a zájmu čitelnosti vhodné) funkce volat s pojmenovanými parametry.

vypis(nazev='Mys sediva', kod='MYS02345', 
        cena_za_kus=27.90, dph=2, 
        pocet=7)

9.4 Implicitní hodnoty parametrů

Při definici funkce je možné povolit vynechání některých parametrů tak, že uvedeme hodnoty, které se mají použít v případě, že parametr není definovaný.

def pricti(a, b=1):
        return a + b

Takto definovanou funkce je potom možné volat se dvěma parametry (které se potom použijí jako hodnota a, b) nebo pouze s jedním parametrem (ten se použije jako a a za b se použije 1).

ADVANCED: V případě, že implicitní hodnota parametru je měnitelná (mutable) je změněna, při dalším volání funkce s použitím implicitní hodnoty bude použita nová hodnota (ne ta, která je zapsaná ve zdrojovém kódu.

9.5 Proměnný počet parametrů

Je-li potřeba předávat funkci proměnný počet parametrů, je možné do definice fuknce za ``obyčejné'' parametry uvést parametr, který má před jménem * (hvězdičku). Při volání funkce se do tohoto parametru umístí seznam všech hodnot, které nebyly přiřazeny do žádného parametru.

>>> def f(a,b,*c):
...     print a,b,c
>>> f(2,3)
2 3 ()
>>> f(2,3,4,5,6)
2 3 (4, 5, 6)
>>> f(5,6,7)
5 6 (7,)

Podobnou možností je uvést v definici před funkcí dvě hvězdičky. Ve funkci potom bude vytvořena proměnná a do ní umístěn slovník. Klíči tohoto slovníku jsou všechny hodnoty, které byly předány pomocí ``keyword calling'' a nenašlo se pro ně vhodné umístění. Všechny výše uvedené metody se samozřejmě dají kombinovat.

Dovolím si výšeuvedené shrnout do několika bodů:


Další Předchozí Obsah