Reference na funkci
V jazyce Python je název funkce bez kulatých závorek chápán jako proměnná obsahující referenci na objekt jež danou funkci reprezentuje. Můžeme tedy udělat následující.
# funkce
def na_druhou(x):
return x ** 2
# volání funkce
print(na_druhou(4)) # vypíše: 16
# vytvoření nové reference na funkci na_druhou
f = na_druhou
# zavolání funkce pomocí nové reference
print(f(4)) # vypíše: 16
Anonymní funkce
Pokud vytváříme funkce pomocí klíčového slova def
, tak je funkce
uložena do proměnné a to je někdy nezádoucí. Proto většina moderních jazyků
umožnňuje vytvořit funkci beze jména. Takovým funkcím říkáme anonymní. Pro vytvoření
anonymní funkce používáme klíčové slovo lambda
:
lambda parametr_1, parametr_2, ..., parametr_n: výraz
Kde parametr_1, parametr_2 až parametr_n jsou parametry funkce, které jsou dostupné v těle anonymní funkce tvořené jedním výrazem výraz.
# zápis funkce pomocí def
def f1(x, y):
return x + y
# zápis funkce pomocí lambda výrazu
f2 = lambda x, y: x + y
# obě funkce se volají stejně
f1(4,2)
f2(4,2)
Výchozí parametry funkce
Někdy je žádoucí, aby parametr funkce měl nějakou výchozí hodnotu.
def f(x=1): # výchozí hodnota parametru x je 1
return x
print(f(42)) # vypíše: 42
print(f()) # vypíše: 1 (výchozí hodnota parametru x)
# Lze použít i v lambda výrazu
f = lambda x=1: x # výchozí hodnota parametru x je 1
print(f(42)) # vypíše: 42
print(f()) # vypíše: 1 (výchozí hodnota parametru x)
# parametr x nemá výchozí hodnotu, y má výchozí hodnotu 1
def f(x, y=1):
return x*y
print(f(42, 10))
print(f(42))
def f(y=1, x):
return x*y
# způsobí chybu: SyntaxError: non-default argument follows default argument
# vyraz seznam=[] se vyhodnotí pouze při prvním volání funkce kde neni predan argument
def pridej_a_secti(x, seznam=[]):
seznam.append(x)
soucet = 0
for i in seznam:
soucet += i
return soucet
print(pridej_a_secti(1, [42, 43])) # vypíše: 86
print(pridej_a_secti(42)) # vypíše: 42
print(pridej_a_secti(43)) # vypíše: 85!
Vnořené funkce
Tělo funkce může obsahovat další funkce, které se bežně označují jako vnořené funkce (nested functions)
# funkce
def f1():
# tělo funkce
# vnořená funkce
def f2():
# tělo vnořené funkce
print("Zanořená funkce")
# volání vnořené funkce f2()
f2()
# volání funkce f1()
f1()
# volání funkce f2()
f2() # způsobí chybu: NameError: name ’f2’ is not defined
# Zanořovat můžeme i anonymní funkce
def f1():
f2 = lambda zprava: print(zprava)
f2("Zanořená funkce")
Rozsah platnosti
a = 42 # globální proměnná
def f1():
a = 0 # nová lokální proměnná
print(a) # vytiskneme lokální proměnnou
f1() # vypíše: 0
Funkce vyšších řá́dů̊
Jako funkce vyššího řádu se označuje funkce, která akceptuje jako parametry jiné funkce nebo vrací funkci jako návratovou hodnotu.
# FILTROVÁNÍ
def filtrovani(f, sekvence):
sekvence_f = []
for i in sekvence:
if f(i):
sekvence_f.append(i)
return sekvence_f
sekvence = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
licha_cisla = lambda x: x % 2 != 0
suda_cisla = lambda x: x % 2 == 0
sekvence_licha_cisla = filtrovani(licha_cisla, sekvence)
print(sekvence_licha_cisla) # vypíše: [1, 3, 5, 7, 9]
sekvence_suda_cisla = filtrovani(suda_cisla, sekvence)
print(sekvence_suda_cisla) # vypíše: [2, 4, 6, 8, 10]
# Jazyk Python obsahuje funkci filter
sekvence = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sekvence_licha_cisla = filter(lambda x : x % 2 != 0,
sekvence)
print(sekvence_licha_cisla) # vypíše: [1, 3, 5, 7, 9]
Funkce vracející funkci
def vytvor_funkci_na_n(n):
# parametr n je lokální proměnná
def na_n(x):
print(x ** n)
# lokální funkce je vrácena jako návratová hodnota
return na_n
na_druhou = vytvor_funkci_na_n(2)
na_druhou(4) # vypíše: 16
na_treti = vytvor_funkci_na_n(3)
na_treti(4) # vypíše: 64
# To samé pomocí anonymní funkce
def vytvor_funkci_na_n(n):
return lambda x : print(x ** n)
na_druhou = vytvor_funkci_na_n(2)
na_druhou(4) # vypíše: 16