Vlastní funkce
Po vysvětlení pojmu funkce, jejich významu, použití, interakce s ostatními částmi programu pomocí parametrů a návratové hodnoty nám již nic nebrání, abychom si ukázali, jak v Pythonu lze vytvářet vlastní funkce.
Výpočet faktoriálu
Postup si ukážeme na konkrétním příkladu - výpočet faktoriálu nezáporného celého čísla.
- faktorial3.py
# definice funkce na výpočet faktoriálu def faktorial(n): """ výpočet faktoriálu návratová hodnota (typu int) je vypočtena jako n! pro zadané n (nezáporný int) """ if n == 0: return 1 vysledek = n for i in range(2, n): vysledek = vysledek * i return vysledek # příklad použití právě definované funkce: # výpis tabulky hodnot n! v rozsahu 0 až 20 # hlavní program for i in range(21): print(i, '! = ', faktorial(i), sep = '')
Povšimněte si následujících skutečností:
- Řádek definice je ukončen dvojtečkou a od dalšího řádku v odsazeném bloku následuje tělo funkce. Rozsah funkce opět určuje odsazení počátku řádků. Jako u jiných bloků (podmínky, cykly) může tělo funkce obsahovat vnořené bloky.
- Hned za hlavičkou funkce může (ale nemusí) následovat dokumentační řetězec. Jedná se o běžně zapsaný řetězec (uvozený apostrofy, uvozovkami nebo trojitými uvozovkami pro víceřádkové řetězce). Pro činnost funkce nemá žádný význam, slouží k vysvětlení činnosti funkce, významu parametrů, upozorňuje na případná omezení apod. Některé vývojové nástroje využívají dokumentačních řetězců ke zvýšení komfortu programátorů.
- Pokud Python při provádění jednotlivých příkazů narazí na klíčové slovo
return
, ukončí vykonávání funkce a vrátí řízení za místo volání funkce. Případný výraz (konstanta, proměnná) zareturn
se považuje za návratovou hodnotu funkce. V definici funkce může být i více příkazůreturn
, nemusí tam být však žádný - v takovém případě se funkce ukončí za posledním příkazem odsazeného bloku. Pokud není návratová hodnota určena, použije se hodnotaNone
datového typuNoneType
. - Když v těle funkce přiřadíme nějaké proměnné hodnotu, jedná se o lokální proměnnou, která je odlišná od lokálních proměnných v ostatních funkcích i od globálních proměnných v hlavním programu. Tyto lokální proměnné jsou mimo funkci nepřístupné. Pokud uvnitř funkce použijeme proměnnou ve výrazu či jako argument volání jiné funkce, použije se aktuální hodnota lokální proměnné. Takto je realizováno ono dříve zmíněné „oddělení světa funkce a okolí“. Pouze v případě, že lokální proměnná požadovaného jména neexistuje, použije se hodnota globální proměnné. Kromě zvláštních situací je obecně využití globálních proměnných uvnitř funkce považováno za nevhodné! Brání totiž přenositelnosti funkcí a je zdrojem obtížně odhalitelných chyb.
- Pojmenování formálních parametrů v hlavičce funkce je důležité pouze uvnitř funkce. Nemá žádnou spojitost s dosazenými skutečnými parametry (též argumenty).
- Použití naší nové funkce v hlavním programu (nebo v jiných funkcích) by nás již nemělo ničím překvapit, je stejné jako u vestavěných funkcí.
Definici funkce bychom mohli ještě zjednodušit, např. do tvaru
def faktorial(n): if n == 0: return 1 for i in range(2, n): n = n * i return n
Vidíme, že i proměnnou odpovídající některému z parametrů můžeme použít pro výpočty uvnitř funkce, jedná se stále o lokální proměnnou.3)
Skládá-li se náš program z více funkcí, uvádíme je postupně za sebou. Na pořadí přitom nezáleží, je pouze nutné mít definice funkcí před jejich prvním použitím. Proto se hlavní program uvádí až na konci souboru za ostatními funkcemi.
Juliánské datum
Pro určení časových okamžiků v běžném životě používáme občanský kalendář (v současné době gregoriánský). Pro použití např. v astronomii však není příliš vhodný4), tam se spíše setkáme s časovými údaji v juliánských dnech či z nich odvozených veličin.
Jako další příklad napíšeme funkci, která pro platné datum dle současného kalendáře určí číslo juliánského dne5). Použijeme algoritmus dle uvedeného odkazu na Wikipedii (tam hledejte i případné podrobnější vysvětlení).
Naše funkce jul_datum
vyžaduje tři celočíselné parametry (den, měsíc, rok) dle požadovaného data a její návratová hodnota je vypočtené číslo juliánského dne JDN (typu int
). V hlavním programu je ukázáno použití pro zjištění JDN pro zadané datum i určení časového intervalu v dnech mezi dvěma daty.
- julian.py
def jul_datum(den, mesic, rok): """ výpočet juliánského data pro zadaný den, měsíc a rok vypočte juliánské datum (JDN), předpokládá vstupní parametry dle gregoriánského kalendáře (datum musí být platné, parametry kladné int) viz. https://cs.wikipedia.org/wiki/Juli%C3%A1nsk%C3%A9_datum """ if mesic <= 2: r = rok + 4799 n = mesic + 9 else: r = rok + 4800 n = mesic - 3 e = den + (153 * n + 2) // 5 # návratová hodnota typu int return e + 365 * r + r // 4 - r // 100 + r // 400 - 32045 # hlavní program print("1.1.2000 =>", jul_datum(1, 1, 2000)) print("Dní mezi 15.9.2009 a 15.9.2010:", \ jul_datum(15, 9, 2010) - jul_datum(15, 9, 2009)) print("Dní mezi 15.9.2011 a 15.9.2012:", \ jul_datum(15, 9, 2012) - jul_datum(15, 9, 2011))
n
se funkci range
předává pouze jednou (tj. před změnou své hodnoty), takže výpočet proběhne podle našeho očekávání.