Kódím.cz
4

Obsluha výjimek

Jak ošetřit chybové stavy v programu pomocí bloku try/except

Různé přístupy k ošetřování chyb

Ještě než se pustíme do samotného ošetřování výjimek, povíme si něco o ošetřování vstupů programu. Pokud totiž program nemá žádné vstupy "zvenku", není příliš univerzální. Takový program by se choval vždy stejně a vypsal by jen to, co jsme mu zadrátovali uvnitř (např. text "Hello world!").

Důležité je si pod pojmem vstup programu představit mnoho různých věcí, např.:

  • Návratovou hodnotu funkce input() - vstup textu z klávesnice
  • Parametry předané programu přes příkazovou řádku(sys.argv)
  • Data z načítaného souboru
  • Data stažená přes internet z API nebo webové stránky
  • Formuláře na webové stránce (viz xkcd komix)
  • Posloupnost klikání na tlačítka a jiné prvky u GUI aplikací

Všechny tyto vstupy mohou způsobit v našem programu chyby, kterým se vždy musíme snažit předejít. K tomu se používají dva hlavní přístupy.

Nejprve otestuj a pak proveď

Uvažujme, že chceme převést uživatelský vstup na číslo. U tohoto přístupu nejprve ověříme, že vstup obsahuje pouze číslice, a to například s využitím metody .isdigit(). Tato metoda vrátí True, pokud jsou v řetězci pouze čísla, v opačném případě vrátí False. V našem programu tedy řetězec zkontrolujeme a pokud obsahuje jiné znaky než číslice, ukončíme program pomocí funkce exit(). Řádek převodem řetězce na číslo bude tedy spuštěn pouze v případě, že řetězec obsahuje pouze čísla a tím pádem probehne korektně.

import sys

vek = input("Zadej věk: ")
if not vek.isdigit():
    print("Je třeba zadat číslo!")
    sys.exit()
vek = int(vek)
if vek > 15:
    print("Vítej")
else:
    print("Představení je až od 15 let.")

Tento přístup se v angličtině označuje slovy Look Before You Leap (LBYL).

Proveď a řeš až problémy

Protože provedení všech potřebných kontrol by bylo v řadě případů příliš komplikované, byl v mnoha programovacích jazycích vytvořen mechanismus obsluhy výjimek. Kromě Pythonu jsou to např. jazyky C++, Java nebo C#. Slouží k tomu nová klíčová slova try a except. Kus kódu, ve kterém může dojít k chybě, "obalíme" blokem try. Za tím to blokem odchytíme příslušnou chybu v bloku except. Předchozí příklad přepíšeme následujícím způsobem:

try:
    vek = input("Zadej věk: ")
    vek = int(vek) # Zde se pokoušíme o převod
    if vek > 15:
        print("Vítej")
    else:
        print("Představení je až od 15 let.")
except ValueError:  # Zde odchytáváme chybu při převodu
    print("Je třeba zadat číslo!")

Pokud by program získal vstup, který není možné převést na číslo, funkce int() vyvolá chybu ValueError. Protože ale máme v programu blok except ValueError, nedojde k ukončení programu neošetřenou chybou. Namísto toho program provede kód, který je v bloku except ValueError a může dále pokračovat. V případě ošetření výjimky totiž Python předpokládá, že problémy, které mohlo chybné zadání způsobit, jsou již v tomto bloku ošetřeny a program může pokračovat dále.

Tento přístup se v angličtině označuje slovy Easier to Ask Forgiveness Than Permission (EAFP) a za jeho úvodní autorku je označována admirálka Grace Hopper.

V reálném životě samozřejmě můžeme kombinovat oba přístupy, tj. známé komplikace ošetříme pomocí předběžných kontrol, ale doplníme i ošetření výjimek pro případ dalších chyb.

Cvičení

Bonusy