33Pojďme si prohloubit znalosti o chybách, neboli odborně o * výjimkách*
44(angl. * exceptions* ).
55
6- Vezmi následující funkci:
6+ Podívej se na následující funkci:
77
88``` python
99def nacti_cislo ():
10+ """ Získá od uživatele celé číslo a vrátí ho"""
1011 odpoved = input (' Zadej číslo: ' )
1112 return int (odpoved)
1213```
1314
1415Když uživatel nezadá číslice, ale třeba text ` cokolada ` ,
1516nastane výjimka jménem ` ValueError ` (chyba hodnoty) a Python vypíše
16- odpovídající chybovou hlášku.
17+ odpovídající chybovou hlášku:
1718
1819``` pycon
1920Traceback (most recent call last):
20- File "ukazka.py", line 3 , in nacti_cislo
21+ File "ukazka.py", line 4 , in nacti_cislo
2122 cislo = int(odpoved)
2223ValueError: invalid literal for int() with base 10: 'cokolada'
2324```
@@ -27,14 +28,15 @@ Co s tím má chudák funkce `int` dělat?
2728Není žádná rozumná hodnota, kterou by mohla vrátit.
2829Převádění tohoto textu na celé číslo nedává smysl.
2930
30- Až funkce ` nacti_cislo ` nejlíp „ví“, co se má stát, když uživatel nezadá
31+ Až funkce ` nacti_cislo ` nejlíp „ví“, co se má stát když uživatel nezadá
3132číslice.
3233Stačí se uživatele zeptat znovu!
3334Kdybys měl{{a}} funkci, která zjistí jestli jsou v řetězci jen číslice,
3435mohlo by to fungovat nějak takhle:
3536
3637``` python
3738def nacti_cislo ():
39+ """ Získá od uživatele celé číslo a vrátí ho"""
3840 while True :
3941 odpoved = input (' Zadej číslo: ' )
4042 if obsahuje_jen_cislice(odpoved):
@@ -47,20 +49,20 @@ def nacti_cislo():
4749Kde ale vzít funkci ` obsahuje_jen_cislice ` ?
4850Nemá smysl ji psát znovu – funkce ` int ` sama nejlíp pozná, co se dá převést na
4951číslo a co ne.
50- A dokonce nám to dá vědět – chybou , kterou můžeš * zachytit* .
52+ A dokonce nám to dá vědět – výjimkou , kterou můžeš * zachytit* .
5153
5254> [ note]
5355> Ono „obsahuje_jen_cislice“ v Pythonu existuje. Dokonce několikrát.
5456> Místo řešení problému to ale spíš ilustruje, v čem problém spočívá:
5557> * Řetězcová metoda ` isnumeric ` vrací ` True ` pokud řetězec obsahuje číslice:
5658> ` '123'.isnumeric() ` je pravda; ` 'abc'.isnumeric() ` nepravda.
57- > Problém je, že funkci ` int ` potřebuje jeden konkrétní druh číslic:
58- > pro řetězce jako ` '½' ` nebo ` '௩三๓໓ ` ' (trojka v tamilském, japonském,
59- > thajském nebo laoském písmu) platí ` isnumeric ` , ale ` int ` si na nich
59+ > Problém je, že funkce ` int ` potřebuje jeden konkrétní druh číslic:
60+ > pro řetězce jako ` '½' ` nebo ` '௩三๓໓ ` ' (trojky v tamilském, japonském,
61+ > thajském a laoském písmu) platí ` isnumeric ` , ale ` int ` si na nich
6062> vyláme zuby stejně jako na ` 'abc' ` .
6163> * Řetězcová metoda ` isdecimal ` vrací ` True ` pokud řetězec obsahuje arabské
6264> číslice 0-9. To už je lepší, ale stejně to úplně nesedí: ` int ` si poradí
63- > s mezerou na začátku, např. s ` ' 3' ` , ale funkce ` isdecimal ` takový řetězec
65+ > s mezerou na začátku, např. s ` ' 3' ` . Funkce ` isdecimal ` ale takový řetězec
6466> odmítne.
6567>
6668> Chceš-li zjistit jestli funkce ` int ` umí daný řetězec převést na číslo,
@@ -73,17 +75,19 @@ Pro zachycení chyby má Python příkaz `try`/`except`.
7375
7476``` python
7577def nacti_cislo ():
78+ """ Získá od uživatele celé číslo a vrátí ho"""
7679 while True :
7780 odpoved = input (' Zadej číslo: ' )
7881 try :
7982 return int (odpoved)
8083 except ValueError :
8184 print (' To nebylo číslo!' )
85+ # ... a zeptáme se znovu -- cyklus `while` pokračuje
8286```
8387
8488Jak to funguje?
8589Příkazy v bloku uvozeném příkazem ` try ` se normálně provádějí, ale když
86- nastane uvedená výjimka, Python přeskočí zbytek bloku ` try ` a provede všechno
90+ nastane uvedená výjimka, Python přeskočí zbytek bloku ` try ` a provede všechno
8791v bloku ` except ` .
8892Pokud výjimka nenastala, přeskočí se celý blok ` except ` .
8993
@@ -141,10 +145,10 @@ V našem příkladu to platí pro `ValueError` z funkce `int`: víš že uživ
141145nemusí vždy zadat číslo ve správném formátu a víš že správná
142146reakce na tuhle situaci je problém vysvětlit a zeptat se znovu.
143147
144- Co ale dělat, kdyš uživatel chce ukončit program a zmáčkne
148+ Co ale dělat, když uživatel chce ukončit program a zmáčkne
145149<kbd >Ctrl</kbd >+<kbd >C</kbd >?
146150Nebo když se mu porouchá klávesnice a selže funkce ` input ` ?
147- Nejlepší reakce na takovou nečekanou situaci ukončit program a informovat
151+ Nejlepší reakce na takovou nečekanou situaci je ukončit program a informovat
148152uživatele (nebo lépe, programátora), že (a kde) je něco špatně.
149153Neboli vypsat chybovou hlášku.
150154A to se stane normálně, bez ` try ` .
@@ -204,22 +208,23 @@ funkce mohla vrátit.
204208Místo vrácení výsledku musí tato funkce * signalizovat chybu* .
205209S tou se pak může program, který ` obsah_ctverce(-5) ` zavolal,
206210vypořádat – vynadat uživateli, zkalibrovat měřák, nebo, pokud na chybu není
207- připravený, sám skončit s chybou ( a upozornit tak programátora, že je něco
208- špatně) .
211+ připravený, sám skončit s chybou a upozornit tak programátora, že je něco
212+ špatně.
209213
210214Jak na to prakticky?
211215Chybu můžeš vyvolat pomocí příkazu ` raise ` .
212216Za příkaz dáš druh výjimky a pak do závorek nějaký popis toho, co je špatně.
213217
214218``` python
215219def obsah_ctverce (strana ):
220+ """ Vrátí obsah čtverce s danou délkou strany"""
216221 if strana > 0 :
217222 return strana ** 2
218223 else :
219224 raise ValueError (f ' Strana musí být kladná, číslo { strana} kladné není! ' )
220225```
221226
222- Podobně jako ` return ` , i příkaz ` raise ` ukončí funkci.
227+ Podobně jako ` return ` i příkaz ` raise ` ukončí funkci.
223228A nejen tu – pokud na tuhle konkrétní chybu není program předem připravený,
224229ukončí se celý program.
225230
0 commit comments