InterSystems B.V.
Funkce a způsoby předávání parametrů
Jython, i když je objektově orientovaný,
                  nepodporuje přetěžování funkcí. Toto je vynahrazeno
                  širokou paletou možností, jak předávat parametry.
                  Tyto, níže popsané vlastnosti, Java nepodporuje.
Funkce s nepovinnými argumenty
Kromě standardního způsobu definování funkce, je
                  možné funkci definovat s proměnným počtem argumentů
                  tak, že pro nepovinné argumenty nadefinujeme jejich
                  defaultní hodnoty.
def fceNepovArg(x, a=2, b='treti'):
print x, a, b
Způsoby volání výše definované funkce jsou
                  následující:
>>> fceNepovArg(0)
0 2 treti
>>>
>>> fceNepovArg(0, 111)
0 111 treti
>>>
>>> fceNepovArg(0, 'Ahoj')
0 Ahoj treti
>>>
>>> fceNepovArg(0, a='Cau')
0 Cau treti
>>>
>>> fceNepovArg(0, b='III')
0 2 III
>>>
>>> fceNepovArg(x=0, a=123, b='III')
0 123 III
Výrazy definující defaultní hodnoty nepovinných
                  parametrů, se nevyhodnocují při každém volání funkce,
                  ale pouze jednou, a to tehdy, když je vykonáván
                  příkaz definice funkce.
>>> a = 1
>>>
>>> def f(x = a): #zacatek definice funkce
... print x
...
>>>
>>> f() #pouziju defaultni hodnotu
1
>>>
>>> f(123) #zadam svoji hodnotu
123
>>>
>>> a = 999
>>> f() #defaultni hodnota pouzije puvodni hodnotu
1
>>>
Volitelný seznam argumentů
Pokud je seznam argumentů ukončen argumentem, který
                  obsahuje jako první znak *,  například
                  *volitelny, pak argument obdrží tuple
                  obsahující všechny přebývající parametry při volání
                  funkce:
>>> def f(x, a='druhy', *volitelne):
... print x, a, volitelne
...
>>>
>>> f(1)
1 druhy ()
>>>
>>>
>>> f(1,2)
1 2 ()
>>>
>>>
>>> f(1,2, 3, 4)
1 2 (3, 4)
>>>
>>> f(1, 'backora', 999, 'konec')
1 backora (999, 'konec')
Definice funkce, která může obsahovat libovolný
                  počet argumentů, ale nemusí mít žádný, může začínat
                  takto:
>>> def fce(*params):
... print params
...
>>> fce()
()
>>>
>>> f('a', [1,2,3], {1: "ichi", 2: "ni"})
('a', [1, 2, 3], {2: 'ni', 1: 'ichi'})
>>>
Konečná syntaxe definice funkce je následující:
def nazevFunkce([arg, …[, *zbytek[, **argKlicSlov]]])
blok
Následující příklad osvětlí význam posledního typu
                  parametru, který, pokud jej chceme použít, musí následovat za volitelným parametrem
                  *zbytek.
>>> def f(a, b=0, c='ahoj', *d, **e):
... print a, b, c, d, e
...
>>> f(1)
1 0 ahoj () {}
>>>
>>> f(1, 111)
1 111 ahoj () {}
>>>
>>> f(1, 2, 3, 4, 5, 6)
1 2 3 (4, 5, 6) {}
>>>
>>> f(1, 2, 3, typ='Wokenice', program='Wod Bila')
1 2 3 () {'program': 'Wod Bila', 'typ': 'Wokenice'}
>>>
>>> f(1, 2, 3, 4, 5, typ='Wokenice', program='Wod Bila')
1 2 3 (4, 5) {'program': 'Wod Bila', 'typ': 'Wokenice'}
>>>
Funkcionální programování
Ukázky kódu, se kterými jsme se doposud setkávali,
                  byly psány způsobem blízkým procedurálnímu
                  programování. Na Jythonu je sympatické, že vám
                  nevnucuje, jakým způsobem máte své programy psát.
                  Můžete používat procedurální způsob, objektově
                  orientovaný způsob či funkcionální.
Lambda výrazy
Klíčové slovo lambda vám umožní
                  vytvářet malé anonymní funkce. Termín lambda výraz je výstižný, neboť lambda výraz
                  nesmí obsahovat příkazy. Syntaxe lambda výrazu je
                  následující:
lambda seznam_parametru: vyraz
Ukažme si rozdíl mezi procedurálním a funkcionálním
                  způsobem naprogramování funkce, která nám řekne, zda
                  její argument je liché či sudé číslo:
>>># proceduralni zpusob programovani
>>>
>>> suda_licha(cislo):
... if cislo%2:
... return 'licha'
... else:
... return 'suda'
...
>>> suda_licha(6)
'suda'
>>>
>>> suda_licha(3)
'licha'
>>>
>>>############################################
>>># vyuziti lambda vyrazu
>>>
>>> suda_licha = lambda cislo: cislo % 2 and "licha" or "suda"
>>>
>>> suda_licha(6)
'suda'
>>> suda_licha(3)
'licha'
>>>
>>>
>>>############################################
>>>coz lze take zapsat takto
>>>
>>> suda_licha(cislo):
... return cislo % 2 and "licha" or "suda"
...
>>> suda_licha(6)
'suda'
>>>
>>> suda_licha(3)
'licha'
>>>
Seznam argumentů pro lambda výrazy má stejné
                  vlastnosti, jako v případě uživatelsky definovaných
                  funkcí.
>>>#funkce vrati definici funkce, kterou pouziju dale
>>> def objemValce(vyska):
... return lambda r, pi=3.14, vyska=vyska: pi*r**2 * vyska
...
>>> #zajimaji me objemy valce s ruznym polomerem a s vyskou 10
>>> objemy_pri_vysce_10 = objemValce(10)
>>>
>>> for r in range(1, 6):
... print 'polomer:', r, 'objem:', objemy_pri_vysce_10(r)
...
polomer: 1 objem: 31.400000000000002
polomer: 2 objem: 125.60000000000001
polomer: 3 objem: 282.6
polomer: 4 objem: 502.40000000000003
polomer: 5 objem: 785.0
>>>
Protože lambda výrazy nemohou obsahovat příkazy
                  (jako např. if/else, …), často se v
                  nich používají operátory and/or pro
                  implementaci logiky vyhodnocování výrazů.
>>> faktorial = lambda cislo: cislo==1 or cislo * faktorial(cislo-1)
>>> faktorial(5)
120
Lambda funkce se jeví jako účinný nástroj ve
                  spolupráci s dalšími funkcemi definovanými v Jythonu.
                  Příkladem může být funkce filter,
                  kterou lze výhodně použít při práci se seznamy. Její
                  syntaxe je následující:
filter(nazev_funkce, seznam)
Tuto funkci obecně použijete tam, kde potřebujete
                  ze seznamu vybrat prvky na základě určitého kritéria.
>>> #suda cisla ze seznamu
>>> filter(lambda x: x%2 == 0, range(10))
[0, 2, 4, 6, 8]
Závěrem si ukažme hezký příklad použití funkce
                  filter, kterým je úloha najití průniku
                  dvou množin:
>>> set1 = range(0,200, 7)
>>> set2 = range(0,200, 3)
>>>
>>> filter(lambda x: x in set1, set2)
[0, 21, 42, 63, 84, 105, 126, 147, 168, 189]
