3
3
Pojďme si prohloubit znalosti o chybách, neboli odborně o * výjimkách*
4
4
(angl. * exceptions* ).
5
5
6
- Vezmi následující funkci:
6
+ Podívej se na následující funkci:
7
7
8
8
``` python
9
9
def nacti_cislo ():
10
+ """ Získá od uživatele celé číslo a vrátí ho"""
10
11
odpoved = input (' Zadej číslo: ' )
11
12
return int (odpoved)
12
13
```
13
14
14
15
Když uživatel nezadá číslice, ale třeba text ` cokolada ` ,
15
16
nastane 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:
17
18
18
19
``` pycon
19
20
Traceback (most recent call last):
20
- File "ukazka.py", line 3 , in nacti_cislo
21
+ File "ukazka.py", line 4 , in nacti_cislo
21
22
cislo = int(odpoved)
22
23
ValueError: invalid literal for int() with base 10: 'cokolada'
23
24
```
@@ -27,14 +28,15 @@ Co s tím má chudák funkce `int` dělat?
27
28
Není žádná rozumná hodnota, kterou by mohla vrátit.
28
29
Převádění tohoto textu na celé číslo nedává smysl.
29
30
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á
31
32
číslice.
32
33
Stačí se uživatele zeptat znovu!
33
34
Kdybys měl{{a}} funkci, která zjistí jestli jsou v řetězci jen číslice,
34
35
mohlo by to fungovat nějak takhle:
35
36
36
37
``` python
37
38
def nacti_cislo ():
39
+ """ Získá od uživatele celé číslo a vrátí ho"""
38
40
while True :
39
41
odpoved = input (' Zadej číslo: ' )
40
42
if obsahuje_jen_cislice(odpoved):
@@ -47,20 +49,20 @@ def nacti_cislo():
47
49
Kde ale vzít funkci ` obsahuje_jen_cislice ` ?
48
50
Nemá smysl ji psát znovu – funkce ` int ` sama nejlíp pozná, co se dá převést na
49
51
čí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* .
51
53
52
54
> [ note]
53
55
> Ono „obsahuje_jen_cislice“ v Pythonu existuje. Dokonce několikrát.
54
56
> Místo řešení problému to ale spíš ilustruje, v čem problém spočívá:
55
57
> * Řetězcová metoda ` isnumeric ` vrací ` True ` pokud řetězec obsahuje číslice:
56
58
> ` '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
60
62
> vyláme zuby stejně jako na ` 'abc' ` .
61
63
> * Řetězcová metoda ` isdecimal ` vrací ` True ` pokud řetězec obsahuje arabské
62
64
> čí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
64
66
> odmítne.
65
67
>
66
68
> 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`.
73
75
74
76
``` python
75
77
def nacti_cislo ():
78
+ """ Získá od uživatele celé číslo a vrátí ho"""
76
79
while True :
77
80
odpoved = input (' Zadej číslo: ' )
78
81
try :
79
82
return int (odpoved)
80
83
except ValueError :
81
84
print (' To nebylo číslo!' )
85
+ # ... a zeptáme se znovu -- cyklus `while` pokračuje
82
86
```
83
87
84
88
Jak to funguje?
85
89
Pří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
87
91
v bloku ` except ` .
88
92
Pokud výjimka nenastala, přeskočí se celý blok ` except ` .
89
93
@@ -141,10 +145,10 @@ V našem příkladu to platí pro `ValueError` z funkce `int`: víš že uživ
141
145
nemusí vždy zadat číslo ve správném formátu a víš že správná
142
146
reakce na tuhle situaci je problém vysvětlit a zeptat se znovu.
143
147
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
145
149
<kbd >Ctrl</kbd >+<kbd >C</kbd >?
146
150
Nebo 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
148
152
uživatele (nebo lépe, programátora), že (a kde) je něco špatně.
149
153
Neboli vypsat chybovou hlášku.
150
154
A to se stane normálně, bez ` try ` .
@@ -204,22 +208,23 @@ funkce mohla vrátit.
204
208
Místo vrácení výsledku musí tato funkce * signalizovat chybu* .
205
209
S tou se pak může program, který ` obsah_ctverce(-5) ` zavolal,
206
210
vypořá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ě.
209
213
210
214
Jak na to prakticky?
211
215
Chybu můžeš vyvolat pomocí příkazu ` raise ` .
212
216
Za příkaz dáš druh výjimky a pak do závorek nějaký popis toho, co je špatně.
213
217
214
218
``` python
215
219
def obsah_ctverce (strana ):
220
+ """ Vrátí obsah čtverce s danou délkou strany"""
216
221
if strana > 0 :
217
222
return strana ** 2
218
223
else :
219
224
raise ValueError (f ' Strana musí být kladná, číslo { strana} kladné není! ' )
220
225
```
221
226
222
- Podobně jako ` return ` , i příkaz ` raise ` ukončí funkci.
227
+ Podobně jako ` return ` i příkaz ` raise ` ukončí funkci.
223
228
A nejen tu – pokud na tuhle konkrétní chybu není program předem připravený,
224
229
ukončí se celý program.
225
230
0 commit comments