2.25. Zpracování chyb

Většina běhových problémů v Pythonu se projeví jako výjimky – pojmenovaný, strukturovaný způsob, jak ohlásit, že se něco pokazilo. ValueError, TypeError, KeyError, OSError, MemoryError jsou všechno příklady; každá je třídou a její vyvolání zastaví aktuální volání a hledá obslužnou rutinu v okolním kódu.

2.25.1. try / except

Obalte blok kódu do try, abyste zachytili jakoukoli výjimku, kterou vyvolá:

try:
    n = int(input_text)
except ValueError:
    n = 0

Pokud převod int(...) selže, řízení skočí do bloku except místo dalšího šíření chyby. Pokud byl input_text platným celočíselným řetězcem, blok except se přeskočí.

Jediný try může mít několik bloků except, z nichž každý zachytává jiný druh chyby:

try:
    value = data[key]
except KeyError:
    value = None
except TypeError:
    value = -1

Python porovnává v pořadí; problém vyřeší první z nich, jehož třída výjimky odpovídá. Zachycení Exception (základní třídy téměř pro vše) zpracuje jakoukoli chybu; vyhraďte si to pro nejvnější vrstvu programu, kde je alternativou pád.

Varování

Holé except: (bez třídy za klíčovým slovem) zachytí i KeyboardInterrupt – výjimku, kterou IDE odešle, když stisknete jeho tlačítko stop pro přerušení běžícího skriptu. Smyčka obalená holým except: pass přerušení spolkne a poběží dál, takže nezůstane jiný způsob, jak skript zastavit, než vypnutí a zapnutí napájení.

Dejte přednost except Exception: před holým except:, když skutečně potřebujete zachytávat široce. KeyboardInterrupt dědí z BaseException, nikoli z Exception, takže except Exception: ponechá tlačítko stop funkční.

2.25.1.1. Zkoumání výjimky

Chcete-li přečíst zprávu připojenou k výjimce, pojmenujte ji pomocí as:

try:
    f = open("data.txt")
except OSError as e:
    print("could not open file:", e)

Proměnná navázaná pomocí as je platná pouze uvnitř bloku except.

2.25.2. else a finally

Blok try má dvě volitelné doplňky.

else se spustí pouze tehdy, když try skončil bez vyvolání výjimky:

try:
    value = compute()
except ValueError:
    print("bad input")
else:
    print("got", value)

Umístění „co dělat, když to fungovalo“ do else udržuje blok try úzký – do try patří jen řádek, který může selhat.

finally se spustí na konci za všech okolností – ať už try uspěl, vyvolal výjimku, která byla zpracována, nebo vyvolal výjimku, která se chystá šířit dál:

try:
    do_work()
finally:
    cleanup()
Diagram toku ukazující čtyři možné cesty skrz try / except / else / finally: úspěch jde do else, poté do finally; zachycená výjimka jde do except, poté do finally; nezachycená výjimka jde do finally a poté se šíří dál.

finally se spustí vždy. else se spustí pouze na cestě bez výjimky.

Pro většinu vzorů získej/uvolni dejte přednost kontextovému správci před dvojicí try / finally – prostředek si pak spravuje vlastní úklid sám.

2.25.3. Běžné vestavěné výjimky

Krátký seznam výjimek, na které budete narážet často:

  • ValueError – správný typ, špatná hodnota (bytes([300]) – 300 je správný typ, ale je mimo platný rozsah bytu 0..255).

  • TypeError – úplně špatný typ (len(42)).

  • KeyError – chybějící klíč ve dict.

  • IndexError – index za koncem sekvence.

  • AttributeError – přístup k atributu, který neexistuje ("abc".foo).

  • OSError – selhání souborového systému nebo I/O.

  • MemoryError – došla halda. V běhovém prostředí s omezenou pamětí k tomu může dojít během běžného provozu – nejen v patologických případech.