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.
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).
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)
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.
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ů:
*par
pouze jednou a to až za ``normálními'' parametry
(jsou-li nějaké).*dict
pouze jednou
a to až jako poslední položka.