Dříve jsme volaly funkce, které napsal někdo jiný:
print('Ahoj světe!')
Dnes si ukážeme, jak psát funkce vlastní.
Není to tak složité:
def obvod_obdelnika(sirka, vyska):
"Vrátí obvod obdélníka daných rozměrů"
return 2 * (sirka + vyska)
print(obvod_obdelnika(4, 2))
Jak to funguje?
Funkce se definuje příkazem def
, za nějž napíšeš jméno funkce,
pak do závorky seznam argumentů, které funkce bere, a pak dvojtečku.
Potom následuje odsazené tělo funkce – příkazy, které funkce provádí. Tělo může začít dokumentačním řetězcem, který popisuje, co funkce dělá.
Příkazem return
pak můžeš z funkce
vrátit nějakou hodnotu.
Tělo funkce může mít více příkazů, včetně podmínek, cyklů a podobně:
def napis_hlasku(nazev, skore):
"Popíše skóre. Název má být přivlastňovací přídavné jméno."
print(nazev, 'skóre je', skore)
if skore > 1000:
print('Světový rekord!')
elif skore > 100:
print('Skvělé!')
elif skore > 10:
print('Ucházející.')
elif skore > 1:
print('Aspoň něco')
else:
print('Snad příště.')
napis_hlasku('Tvoje', 256)
napis_hlasku('Protivníkovo', 5)
Při volání funkce se hodnoty, se kterými funkci
zavoláš, přiřadí jednotlivým argumentům.
Takže když zavoláš třeba napis_hlasku('Tvoje', 256)
,
můžeš si představit, že funkce dělá následující:
nazev = 'Tvoje'
skore = 256
print(nazev, 'skóre je', skore)
if skore > 1000:
... # atd.
Speciální příkaz return
, který jde použít jenom ve funkcích,
ukončí funkci a vrátí danou hodnotu ven z funkce.
Chová se tedy trochu jako break
, jen místo cyklu opouští celou funkci.
def ano_nebo_ne(otazka):
"Vrátí True nebo False, podle odpovědi uživatele"
while True:
odpoved = input(otazka)
if odpoved == 'ano':
return True
elif odpoved == 'ne':
return False
else:
print('Nerozumím! Odpověz "ano" nebo "ne".')
if ano_nebo_ne('Chceš si zahrát hru? '):
print('OK! Ale napřed si ji musíš naprogramovat.')
else:
print('Škoda.')
Stejně jako if
nebo break
je return
příkaz, ne funkce.
Kolem „své“ hodnoty nepotřebuje závorky.
Zkus napsat funkci, která vrátí obsah elipsy daných rozměrů. Příslušný vzoreček je A = πab, kde a a b jsou délky os.
Funkci zavolej a výsledek vypiš.
Předchozí program se dá napsat i takto:
from math import pi
def obsah_elipsy(a, b):
print('Obsah je', pi * a * b) # Pozor, `print` místo `return`!
obsah_elipsy(3, 5)
Program takhle funguje, ale přichází o jednu z hlavních výhod funkcí:
možnost vrácenou hodnotu použít i jinak jež jen v print
.
Funkci, která výsledek vrací, můžeš použít v dalších výpočtech:
def objem_eliptickeho_valce(a, b, vyska):
return obsah_elipsy(a, b) * vyska
print(objem_eliptickeho_valce(3, 5, 3))
... ale kdyby výsledek přímo vypsala, nešlo by to.
Další důvod, proč hodnoty spíš vracet než vypisovat, je ten, že jedna funkce se
dá použít v různých situacích.
Funkci s print
by nešlo rozumně použít tehdy, když nás příkazová
řádka vůbec nezajímá.
Třeba v grafické hře, webové aplikaci, nebo pro ovládání robota.
Podobně je to se vstupem: když použiju v rámci své funkce input
, bude se
moje funkce dát použít jen v situacích, kdy je u počítače klávesnice a za ní
člověk.
Proto je lepší funkcím potřebné informace předávat jako argumenty
a input
(nebo textové políčko či měření z čidla robota) nemít ve funkci,
ale vně:
from math import pi
def obsah_elipsy(a, b):
"""Vrátí obsah elipsy s poloosami daných délek"""
# Jen samotný výpočet:
return pi * a * b
# print a input jsou "venku":
x = float(input('Zadej délku poloosy 1: '))
y = float(input('Zadej délku poloosy 2: '))
print('Obsah je', obsah_elipsy(x, y))
Samozřejmě existují výjimky: funkce která přímo vytváří textový výpis,
může používat print
; funkce která načítá textové informace zase input
.
Když ale funkce něco počítá, je dobré v ní print
ani input
nemít.
Když funkce neskončí příkazem return
,
automaticky se vrátí hodnota None
.
Je to hodnota zabudovaná přímo do Pythonu, podobně jako True
nebo False
,
a znamená „nic“.
def nic():
"Tahle funkce nic nedělá"
print(nic())
Gratuluji, umíš definovat vlastní funkce! Zbývá ještě vysvětlit jednu věc: lokální a globální proměnné.
Funkce může používat proměnné „zvnějšku“:
pi = 3.1415926
def obsah_kruhu(polomer):
return pi * polomer ** 2
print(obsah_kruhu(100))
Ale všechny argumenty a všechny proměnné, do kterých funkce přiřazuje, jsou úplně nové proměnné, které nemají nic společného s tím, co je „venku“ kolem funkce.
Těm úplně novým proměnným se říká lokální proměnné (angl. local variables), protože existují jen místně, v rámci volání jedné jediné funkce. Takže tohle nebude fungovat tak, jak se zdá:
x = 0
def nastav_x(hodnota):
x = hodnota # Přiřazení do lokální proměnné!
nastav_x(40)
print(x)
Proměnné, které nejsou lokální, jsou globální – ty existují v celém programu. (Jen ve funkcích, které mají náhodou lokální proměnnou stejného jména, „nejsou vidět“ – to jméno označuje lokální proměnnou.)
Pojďme si to ukázat. Než spustíš tenhle program, zkus předpovědět, co bude dělat. Pak ho pusť, a pokud dělal něco jiného, zkus vysvětlit proč. Pozor, je tam chyták!
from math import pi
obsah = 0
a = 30
def obsah_elipsy(a, b):
obsah = pi * a * b # Přiřazení do `obsah`
a = a + 3 # Přiřazení do `a`
return obsah
print(obsah_elipsy(a, 20))
print(obsah)
print(a)
Zkus odpovědět na tyto otázky:
pi
lokální, nebo globální?obsah
lokální, nebo globální?a
lokální, nebo globální?b
lokální, nebo globální?Jestli ti to celé připadá zmatené a složité, dá se tomu zatím vyhnout dodržováním jednoho pravidla: nepřiřazuj ve funkcích do proměnných, které existují i vně funkce. (Parametr funkce se počítá jako přiřazení.)
{ "data": { "sessionMaterial": { "id": "session-material:2019/pyladies-ostrava-jaro:def-str:0", "title": "VlastnĂ funkce", "html": "\n \n \n\n <h1>Funkce</h1>\n<p><a href=\"/2019/pyladies-ostrava-jaro/beginners/functions/\">Dříve</a> jsme\nvolaly funkce, které napsal někdo jiný:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'Ahoj světe!'</span><span class=\"p\">)</span>\n</pre></div><p>Dnes si ukážeme, jak psát funkce vlastní.</p>\n<p>Není to tak složité:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">obvod_obdelnika</span><span class=\"p\">(</span><span class=\"n\">sirka</span><span class=\"p\">,</span> <span class=\"n\">vyska</span><span class=\"p\">):</span>\n <span class=\"s2\">"Vrátí obvod obdélníka daných rozměrů"</span>\n <span class=\"k\">return</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"p\">(</span><span class=\"n\">sirka</span> <span class=\"o\">+</span> <span class=\"n\">vyska</span><span class=\"p\">)</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">obvod_obdelnika</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">))</span>\n</pre></div><p>Jak to funguje?</p>\n<p>Funkce se <em>definuje</em> příkazem <code>def</code>, za nějž napíšeš jméno funkce,\npak do závorky seznam <em>argumentů</em>, které funkce bere, a pak dvojtečku.</p>\n<p>Potom následuje odsazené <em>tělo funkce</em> – příkazy, které funkce provádí.\nTělo může začít <em>dokumentačním řetězcem</em>, který popisuje, co funkce dělá.</p>\n<p>Příkazem <code>return</code> pak můžeš z funkce\nvrátit nějakou hodnotu.</p>\n<p>Tělo funkce může mít více příkazů, včetně podmínek, cyklů a podobně:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">napis_hlasku</span><span class=\"p\">(</span><span class=\"n\">nazev</span><span class=\"p\">,</span> <span class=\"n\">skore</span><span class=\"p\">):</span>\n <span class=\"s2\">"Popíše skóre. Název má být přivlastňovací přídavné jméno."</span>\n\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">nazev</span><span class=\"p\">,</span> <span class=\"s1\">'skóre je'</span><span class=\"p\">,</span> <span class=\"n\">skore</span><span class=\"p\">)</span>\n <span class=\"k\">if</span> <span class=\"n\">skore</span> <span class=\"o\">></span> <span class=\"mi\">1000</span><span class=\"p\">:</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'Světový rekord!'</span><span class=\"p\">)</span>\n <span class=\"k\">elif</span> <span class=\"n\">skore</span> <span class=\"o\">></span> <span class=\"mi\">100</span><span class=\"p\">:</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'Skvělé!'</span><span class=\"p\">)</span>\n <span class=\"k\">elif</span> <span class=\"n\">skore</span> <span class=\"o\">></span> <span class=\"mi\">10</span><span class=\"p\">:</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'Ucházející.'</span><span class=\"p\">)</span>\n <span class=\"k\">elif</span> <span class=\"n\">skore</span> <span class=\"o\">></span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'Aspoň něco'</span><span class=\"p\">)</span>\n <span class=\"k\">else</span><span class=\"p\">:</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'Snad příště.'</span><span class=\"p\">)</span>\n\n<span class=\"n\">napis_hlasku</span><span class=\"p\">(</span><span class=\"s1\">'Tvoje'</span><span class=\"p\">,</span> <span class=\"mi\">256</span><span class=\"p\">)</span>\n<span class=\"n\">napis_hlasku</span><span class=\"p\">(</span><span class=\"s1\">'Protivníkovo'</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">)</span>\n</pre></div><p>Při volání funkce se hodnoty, se kterými funkci\nzavoláš, přiřadí jednotlivým argumentům.\nTakže když zavoláš třeba <code>napis_hlasku('Tvoje', 256)</code>,\nmůžeš si představit, že funkce dělá následující:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">nazev</span> <span class=\"o\">=</span> <span class=\"s1\">'Tvoje'</span>\n<span class=\"n\">skore</span> <span class=\"o\">=</span> <span class=\"mi\">256</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">nazev</span><span class=\"p\">,</span> <span class=\"s1\">'skóre je'</span><span class=\"p\">,</span> <span class=\"n\">skore</span><span class=\"p\">)</span>\n<span class=\"k\">if</span> <span class=\"n\">skore</span> <span class=\"o\">></span> <span class=\"mi\">1000</span><span class=\"p\">:</span>\n <span class=\"o\">...</span> <span class=\"c1\"># atd.</span>\n</pre></div><h2>Vracení</h2>\n<p>Speciální příkaz <code>return</code>, který jde použít jenom ve funkcích,\n<em>ukončí</em> funkci a vrátí danou hodnotu ven z funkce.</p>\n<p>Chová se tedy trochu jako <code>break</code>, jen místo cyklu opouští celou funkci.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">ano_nebo_ne</span><span class=\"p\">(</span><span class=\"n\">otazka</span><span class=\"p\">):</span>\n <span class=\"s2\">"Vrátí True nebo False, podle odpovědi uživatele"</span>\n <span class=\"k\">while</span> <span class=\"bp\">True</span><span class=\"p\">:</span>\n <span class=\"n\">odpoved</span> <span class=\"o\">=</span> <span class=\"nb\">input</span><span class=\"p\">(</span><span class=\"n\">otazka</span><span class=\"p\">)</span>\n <span class=\"k\">if</span> <span class=\"n\">odpoved</span> <span class=\"o\">==</span> <span class=\"s1\">'ano'</span><span class=\"p\">:</span>\n <span class=\"k\">return</span> <span class=\"bp\">True</span>\n <span class=\"k\">elif</span> <span class=\"n\">odpoved</span> <span class=\"o\">==</span> <span class=\"s1\">'ne'</span><span class=\"p\">:</span>\n <span class=\"k\">return</span> <span class=\"bp\">False</span>\n <span class=\"k\">else</span><span class=\"p\">:</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'Nerozumím! Odpověz "ano" nebo "ne".'</span><span class=\"p\">)</span>\n\n<span class=\"k\">if</span> <span class=\"n\">ano_nebo_ne</span><span class=\"p\">(</span><span class=\"s1\">'Chceš si zahrát hru? '</span><span class=\"p\">):</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'OK! Ale napřed si ji musíš naprogramovat.'</span><span class=\"p\">)</span>\n<span class=\"k\">else</span><span class=\"p\">:</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'Škoda.'</span><span class=\"p\">)</span>\n</pre></div><div class=\"admonition note\"><p>Stejně jako <code>if</code> nebo <code>break</code> je <code>return</code> <em>příkaz</em>, ne funkce.\nKolem „své“ hodnoty nepotřebuje závorky.</p>\n</div><p>Zkus napsat funkci, která vrátí obsah elipsy\ndaných rozměrů.\nPříslušný vzoreček je <var>A</var> = π<var>a</var><var>b</var>,\nkde <var>a</var> a <var>b</var> jsou délky os.</p>\n<p>Funkci zavolej a výsledek vypiš.</p>\n<div class=\"solution\" id=\"solution-0\">\n <h3>Řešení</h3>\n <div class=\"solution-cover\">\n <a href=\"/2019/pyladies-ostrava-jaro/beginners/def/index/solutions/0/\"><span class=\"link-text\">Ukázat řešení</span></a>\n </div>\n <div class=\"solution-body\" aria-hidden=\"true\">\n <div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">math</span> <span class=\"kn\">import</span> <span class=\"n\">pi</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">):</span>\n <span class=\"k\">return</span> <span class=\"n\">pi</span> <span class=\"o\">*</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">b</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'Obsah elipsy s osami 3 cm a 5 cm je'</span><span class=\"p\">,</span> <span class=\"n\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">),</span> <span class=\"s1\">'cm2'</span><span class=\"p\">)</span>\n</pre></div>\n </div>\n</div><h3>Vrátit nebo vypsat?</h3>\n<p>Předchozí program se dá napsat i takto:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">math</span> <span class=\"kn\">import</span> <span class=\"n\">pi</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">):</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'Obsah je'</span><span class=\"p\">,</span> <span class=\"n\">pi</span> <span class=\"o\">*</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">b</span><span class=\"p\">)</span> <span class=\"c1\"># Pozor, `print` místo `return`!</span>\n\n<span class=\"n\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">)</span>\n</pre></div><p>Program takhle funguje, ale přichází o jednu z hlavních výhod funkcí:\nmožnost vrácenou hodnotu použít i jinak jež jen v <code>print</code>.</p>\n<p>Funkci, která výsledek vrací, můžeš použít v dalších výpočtech:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">objem_eliptickeho_valce</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">vyska</span><span class=\"p\">):</span>\n <span class=\"k\">return</span> <span class=\"n\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"n\">vyska</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">objem_eliptickeho_valce</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">))</span>\n</pre></div><p>... ale kdyby výsledek přímo vypsala, nešlo by to.</p>\n<p>Další důvod, proč hodnoty spíš vracet než vypisovat, je ten, že jedna funkce se\ndá použít v různých situacích.\nFunkci s <code>print</code> by nešlo rozumně použít tehdy, když nás příkazová\nřádka vůbec nezajímá.\nTřeba v grafické hře, webové aplikaci, nebo pro ovládání robota.</p>\n<p>Podobně je to se vstupem: když použiju v rámci své funkce <code>input</code>, bude se\nmoje funkce dát použít jen v situacích, kdy je u počítače klávesnice a za ní\nčlověk.\nProto je lepší funkcím potřebné informace předávat jako argumenty\na <code>input</code> (nebo textové políčko či měření z čidla robota) nemít ve funkci,\nale vně:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">math</span> <span class=\"kn\">import</span> <span class=\"n\">pi</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">):</span>\n <span class=\"sd\">"""Vrátí obsah elipsy s poloosami daných délek"""</span>\n <span class=\"c1\"># Jen samotný výpočet:</span>\n <span class=\"k\">return</span> <span class=\"n\">pi</span> <span class=\"o\">*</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">b</span>\n\n<span class=\"c1\"># print a input jsou "venku":</span>\n<span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"nb\">float</span><span class=\"p\">(</span><span class=\"nb\">input</span><span class=\"p\">(</span><span class=\"s1\">'Zadej délku poloosy 1: '</span><span class=\"p\">))</span>\n<span class=\"n\">y</span> <span class=\"o\">=</span> <span class=\"nb\">float</span><span class=\"p\">(</span><span class=\"nb\">input</span><span class=\"p\">(</span><span class=\"s1\">'Zadej délku poloosy 2: '</span><span class=\"p\">))</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'Obsah je'</span><span class=\"p\">,</span> <span class=\"n\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">))</span>\n</pre></div><p>Samozřejmě existují výjimky: funkce která přímo vytváří textový výpis,\nmůže používat <code>print</code>; funkce která načítá textové informace zase <code>input</code>.\nKdyž ale funkce něco počítá, je dobré v ní <code>print</code> ani <code>input</code> nemít.</p>\n<h2>None</h2>\n<p>Když funkce neskončí příkazem <code>return</code>,\nautomaticky se vrátí hodnota <code>None</code>.</p>\n<p>Je to hodnota zabudovaná přímo do Pythonu, podobně jako <code>True</code> nebo <code>False</code>,\na znamená „nic“.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">nic</span><span class=\"p\">():</span>\n <span class=\"s2\">"Tahle funkce nic nedělá"</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">nic</span><span class=\"p\">())</span>\n</pre></div><h2>Lokální proměnné</h2>\n<p>Gratuluji, umíš definovat vlastní funkce!\nZbývá ještě vysvětlit jednu věc: lokální a globální proměnné.</p>\n<p>Funkce může používat proměnné „zvnějšku“:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">pi</span> <span class=\"o\">=</span> <span class=\"mf\">3.1415926</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">obsah_kruhu</span><span class=\"p\">(</span><span class=\"n\">polomer</span><span class=\"p\">):</span>\n <span class=\"k\">return</span> <span class=\"n\">pi</span> <span class=\"o\">*</span> <span class=\"n\">polomer</span> <span class=\"o\">**</span> <span class=\"mi\">2</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">obsah_kruhu</span><span class=\"p\">(</span><span class=\"mi\">100</span><span class=\"p\">))</span>\n</pre></div><p>Ale všechny argumenty a všechny proměnné, do kterých funkce přiřazuje,\njsou <em>úplně nové</em> proměnné, které nemají nic\nspolečného s tím, co je „venku“ kolem funkce.</p>\n<p>Těm úplně novým proměnným se říká\n<em>lokální proměnné</em> (angl. <em>local variables</em>), protože existují\njen místně, v rámci volání jedné jediné funkce.\nTakže tohle nebude fungovat tak, jak se zdá:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">nastav_x</span><span class=\"p\">(</span><span class=\"n\">hodnota</span><span class=\"p\">):</span>\n <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">hodnota</span> <span class=\"c1\"># Přiřazení do lokální proměnné!</span>\n\n<span class=\"n\">nastav_x</span><span class=\"p\">(</span><span class=\"mi\">40</span><span class=\"p\">)</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">)</span>\n</pre></div><p>Proměnné, které nejsou lokální, jsou <em>globální</em> – ty\nexistují v celém programu.\n(Jen ve funkcích, které mají náhodou\nlokální proměnnou stejného jména, „nejsou vidět“ –\nto jméno označuje lokální proměnnou.)</p>\n<p>Pojďme si to ukázat.\nNež spustíš tenhle program,\nzkus předpovědět, co bude dělat.\nPak ho pusť, a pokud dělal něco jiného,\nzkus vysvětlit proč.\nPozor, je tam chyták!</p>\n<div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">math</span> <span class=\"kn\">import</span> <span class=\"n\">pi</span>\n<span class=\"n\">obsah</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n<span class=\"n\">a</span> <span class=\"o\">=</span> <span class=\"mi\">30</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">):</span>\n <span class=\"n\">obsah</span> <span class=\"o\">=</span> <span class=\"n\">pi</span> <span class=\"o\">*</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">b</span> <span class=\"c1\"># Přiřazení do `obsah`</span>\n <span class=\"n\">a</span> <span class=\"o\">=</span> <span class=\"n\">a</span> <span class=\"o\">+</span> <span class=\"mi\">3</span> <span class=\"c1\"># Přiřazení do `a`</span>\n <span class=\"k\">return</span> <span class=\"n\">obsah</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"mi\">20</span><span class=\"p\">))</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">obsah</span><span class=\"p\">)</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">)</span>\n</pre></div><p>Zkus odpovědět na tyto otázky:</p>\n<ul>\n<li>Je proměnná <code>pi</code> lokální, nebo globální?</li>\n<li>Je proměnná <code>obsah</code> lokální, nebo globální?</li>\n<li>Je proměnná <code>a</code> lokální, nebo globální?</li>\n<li>Je proměnná <code>b</code> lokální, nebo globální?</li>\n</ul>\n<div class=\"solution\" id=\"solution-1\">\n <h3>Řešení</h3>\n <div class=\"solution-cover\">\n <a href=\"/2019/pyladies-ostrava-jaro/beginners/def/index/solutions/1/\"><span class=\"link-text\">Ukázat řešení</span></a>\n </div>\n <div class=\"solution-body\" aria-hidden=\"true\">\n <ul>\n<li><code>pi</code> je globální – nepřiřazuje se do ní ve funkci;\nje „vidět“ v celém programu.</li>\n<li>Proměnné <code>obsah</code> jsou v programu dvě – jedna globální,\na jedna je lokální pro funkci <code>obsah_elipsy</code>,\nprotože do ní tahle funkce přiřazuje.</li>\n<li>Proměnné <code>a</code> jsou taky dvě, podobně jako <code>obsah</code>.\nTady byl chyták: příkaz <code>a = a + 3</code> nemá žádný smysl;\ndo <code>a</code> se sice uloží větší číslo, ale vzápětí funkce <code>obsah_elipsy</code> skončí\na její lokální proměnná <code>a</code> přestane existovat.</li>\n<li>Proměnná <code>b</code> je jenom lokální – jako argument funkce <code>obsah_elipsy</code>.</li>\n</ul>\n </div>\n</div><p>Jestli ti to celé připadá zmatené a složité, dá se tomu zatím vyhnout\ndodržováním jednoho pravidla:\n<em>nepřiřazuj ve funkcích do proměnných, které existují i vně funkce.</em>\n(Parametr funkce se počítá jako přiřazení.)</p>\n\n\n " } } }