Funkce

Při programování se často setkáte se situací, kdy se určité části programu dají znova využít na různých místech, a abyste je nemuseli neustále opakovat, vznikla koncepce podprogramu. Podprogram, který vrací při svém ukončení nějaké hodnoty, se nazývá funkce.

Uživatelsky definované funkce

Nejjednodušší forma definice funkce má následující tvar:

def jménoFunkce([arg1, arg2, …]):
    blok

Klíčové slovo def je následováno názvem funkce a nepovinným seznamem argumentů, uzavřeným do kulatých závorek. Závorky jsou součástí definice funkce i v případě, že funkce nemá žádné argumenty. Za závorkami následuje dvojtečka.

Definice funkce neobsahuje specifikaci datového typu hodnoty, kterou bude vracet. Funkce v Jythonu nejenže nedefinují datový typ návratové hodnoty, ale ani nespecifikují, zda vůbec nějakou hodnotu budou vracet. Ve skutečnosti každá funkce v Jythonu  vrací nějakou hodnotu. Pokud tato hodnota není explicitně určena, funkce vrací None

.

Pokud definice funkce obsahuje argumenty, pak tyto argumenty jsou taktéž uváděny bez datových typů.

Zde je ukázka velmi jednoduché funkce, která vlastně vůbec nic nedělá:

>>> def prázdnáFunkce():
...     pass

Definice funkce je při jejím volání zpracována následujícím způsobem. Jistě si pamatujete, že v Jythonu je vše objektem. Tudíž i funkce je objekt, který je vytvořen interpretem jazyka během vykonávání programu a odkaz na tento objekt je uložen v proměnné. Tato proměnná má stejné jméno, jako je název funkce. Funkci následně zavoláme tím způsobem, že aplikujeme operátor volání funkce () na tuto proměnnou.  Ano, vidíte dobře. Kulaté závorky () jsou operátor, jenž je aplikován na proměnnou, která obsahuje odkaz na objekt, reprezentující funkci. Je to patrné z níže uvedeného příkladu:

>>> def jednoduchaFunkce(retezec):
...     print 'Byl zadan retezec: ', retezec
...
>>>
>>> # vytisknu obsah promenne jednoduchaFunkce
>>> print jednoduchaFunkce
<function jednoduchaFunkce at 11403048>
>>>
>>> #zavolam funkci a zadam vstupni parametr
>>> jednoduchaFunkce('Jsem vam to rikal, ze?:)')
Byl zadan retezec:  Jsem vam to rikal, ze?:)

Veškeré důsledky výše uvedeného tvrzení budou probrány později, až se dozvíme více o modulech a jmenných prostorech.

Návratovou hodnotu funkce definujeme pomocí příkazu return. Příkaz return se může v definici funkce vyskytovat libovolněkrát. Kdykoliv se během vykonávání kódu narazí na tento příkaz, ukončí se vykonávání volané funkce a vrátí se hodnota výrazu uvedeného za tímto příkazem. Jelikož datový typ vrácené hodnoty je určován až v době vykonávání funkce, je možné, že funkce může vracet hodnotu, jejíž datový typ je závislý na vstupních parametrech:

>>> def novaFunkce(jakyTyp):
...     if jakyTyp == 's':
...         return 'Vracim retezec'
...     elif jakyTyp == 'i':
...         return 123456
...     else:
...         return None
...
>>> novaFunkce('nic')
>>>
>>> novaFunkce('i')
123456
>>>
>>> novaFunkce('s')
'Vracim retezec'
>>>

Dokumentační řetězec

Je dobrým zvykem, že zdrojový kód obsahuje komentáře, které dokumentují obraty a postupy použité ve vašich programech. Tyto komentáře jsou viditelné, máte-li tyto zdroje k dispozici. Bylo by jistě příjemné mít k dispozici nástroj, který by byl schopen v případě, že nevíte, k jakému účelu je vámi volaná funkce navrhnutá, resp. jaké má argumenty a jaký je jejich význam, tyto informace zobrazit.

V Jythonu takový nástroj existuje a jmenuje dokumentační řetězec. Obsahuje-li funkce dokumentační řetězec, musí být tento řetězec první věcí, která je v těle funkce definována, tj. musí následovat hned na řádku za řádkem obsahující příkaz def. Řetězec je ohraničen z obou stran třemi uvozovkami, které dávají interpretu Jythonu na vědomí, že vše, co je mezi těmito uvozovkami, je víceřádkový komentář, a má speciální význam.

Může to vypadat následovně:

def novaFunkce(jakyTyp):
    """Funkce vraci hodnoty ruzneho datoveho typu.
 
Vstupni parametry:
        's' ... vrati retezec
        'i' ... vrati cislo
        cokoliv jineho vrati 'None'"""
 
    if jakyTyp == 's':
        return 'Vracim retezec'
    elif jakyTyp == 'i':
        return 123456
    else:
        return None

Uložíme-li výše uvedenou definici funkce do souboru, například dokumkom.py, můžeme výhod dokumentačního řetězce využít takto:

D:\Jython\Source codes>jython -i dokumkom.py
>>>
>>> print novaFunkce.__doc__
Funkce vraci hodnoty ruzneho datoveho typu.

    Vstupni parametry:
        's' ... vrati retezec
        'i' ... vrati cislo
        cokoliv jineho vrati 'None'

>>>
>>> novaFunkce('i')
123456
>>>

Kdykoliv potřebujeme zobrazit obsah dokumentačního řetězce nějakého objektu, použijeme obrat:

identifikátorObjektu.__doc__

kde __doc__ ,je atribut objektu, obsahující dokumentační řetězec. Objektem, na který ukazuje proměnná identifikátorObjektu, může být funkce, modul nebo i třída.

Obdobně, jako psaní názvů proměnných, i psaní dokumentačních řetězců, se řídí určitými pravidly. První řádek by měl být pokud možno krátký, obsahující souhrnný popis účelu objektu. Kvůli stručnosti by neměl obsahovat ani název objektu, ani typ objektu. Toto je možné obdržet i jinými metodami. Tato řádka by měla začínat velkým písmenem a končit tečkou.