Jak zachytit více výjimek v Pythonu: Snadný průvodce

V Pythonu je zásadní umět efektivně zachytávat výjimky, protože to pomáhá minimalizovat pády programů. Díky tomu je váš kód robustnější a uživatelsky přívětivější. V tomto článku se zaměříme na to, jak v Pythonu zachytit více výjimek v jediném bloku try/except.

Co jsou výjimky v Pythonu?

V Pythonu představují výjimky způsob, jakým různé části programu komunikují. Tento mechanismus umožňuje jedné části systému signalizovat, že narazila na kritickou chybu, kterou nemůže sama vyřešit.

Došlo-li k chybě, program vyvolá výjimku. Další část kódu, která je schopna chybu zpracovat, tuto výjimku zachytí a vhodně s ní naloží.

Pokud se výjimky neřeší, program se zhroutí. Proto je důležité je zpracovávat, čímž se zvyšuje spolehlivost programu a předchází se jeho neočekávanému ukončení.

V tomto článku předpokládám, že máte základní znalosti o tom, jak nastavit a zpracovávat výjimky, což je popsáno v článku o základech try/except v Pythonu.

Význam zpracování více výjimek v Pythonu

  • Zpracováním více výjimek stejným blokem se snižuje duplicita kódu, což zlepšuje jeho čitelnost, upravitelnost a smazání.
  • Dále tímto způsobem píšete efektivnější kód, protože typ chyby se kontroluje pouze jednou, nikoliv opakovaně.

Zpracování více výjimek

Zachycení více výjimek se týká situace, kdy se několik výjimek řeší stejným blokem except. V Pythonu je možné zachytávat různé výjimky v odlišných blocích except.

Pokud chcete s některými výjimkami zacházet podobně, můžete je zpracovat v jediném bloku. K tomu je potřeba zachytit více výjimek najednou. V této části si ukážeme, jak na to pomocí příkladu.

#1. Zachycení různých výjimek v různých blocích

Představme si program, který přijímá dvě číselné hodnoty a provádí jejich dělení. Pokud uživatel zadá neplatné hodnoty, mohou být vyvolány různé typy výjimek. Chceme konkrétně ošetřit výjimky ValueError a ZeroDivisionError.

Výjimka ValueError se vyvolá, pokud uživatel zadá hodnotu, kterou nelze převést na celé číslo. ZeroDivisionError se objeví, pokud je druhé číslo nulové. V obou případech chceme uživateli zobrazit chybové hlášení: „Zadali jste neplatnou hodnotu“.

K dosažení tohoto cíle můžeme použít následující kód:

try:
    dividend = int(input('Zadejte první číslo: '))
    divisor = int(input('Zadejte druhé číslo: '))
    quotient = dividend / divisor
    print(quotient)
except ValueError as e:
    print("Zadali jste neplatnou hodnotu")
except ZeroDivisionError as e:
    print("Zadali jste neplatnou hodnotu")
except Exception as e:
    print("Něco se pokazilo")

Pokud spustíme výše uvedený kód a zadáme text, který nelze převést na celé číslo, získáme tento výstup:

A pokud zadáme jako druhé číslo 0, bude výsledek následující:

Kód funguje podle očekávání, nicméně si všimněte, že s ValueError a ZeroDivisionError zacházíme podobně. Mezi oběma bloky except se tedy objevuje duplicitní kód. To není ideální, protože v programování se snažíme dodržovat princip DRY (Don’t Repeat Yourself – Neopakuj se).

Místo psaní kódu odděleně můžeme tyto dva bloky sloučit do jednoho, který bude zachytávat více výjimek současně. Tím se vyhneme zbytečnému opakování.

#2. Zachycení více výjimek v jednom bloku except

Pro zachycení více výjimek použijeme n-tici, která specifikuje všechny chyby, které chceme zachytit. Následující příklad ukazuje, jak zachytíme ValueError i ZeroDivisionError v jediném bloku except:

try:
    dividend = int(input('Zadejte první číslo: '))
    divisor = int(input('Zadejte druhé číslo: '))
    quotient = dividend / divisor
    print(quotient)
except (ValueError, ZeroDivisionError) as e:
    print("Zadali jste neplatnou hodnotu")
except Exception as e:
    print("Něco se pokazilo")

Tato implementace je mnohem lepší než předchozí. V podstatě toto je podstatou zpracování více výjimek. Výše uvedený kód funguje stejně jako předtím. Pokud otestujete kód pomocí předchozích příkladů, měl by se chovat stejně:

#3. Identifikace, která výjimka byla zachycena

Výše uvedený kód spustí první blok except, pokud byla zachycena ValueError nebo ZeroDivisionError. V některých případech můžete chtít spustit kód, který je společný pro obě chyby, a zároveň spustit specifický kód pro jednu, ale ne pro druhou chybu.

V tomto případě je nutné nejprve určit, která chyba byla zachycena, a poté spustit odpovídající kód.

Pro zjištění, která výjimka byla zachycena, můžete použít blok if/else uvnitř bloku except. Například:

try:
    dividend = int(input('Zadejte první číslo: '))
    divisor = int(input('Zadejte druhé číslo: '))
    quotient = dividend / divisor
    print(quotient)
except (ValueError, ZeroDivisionError) as e:
    print("Zadali jste neplatnou hodnotu")

    if isinstance(e, ValueError):
        print('Chyba hodnoty')
    else:
        print('Chyba dělení nulou')
except Exception as e:
    print("Něco se pokazilo")

Kromě vypsání obecné chybové zprávy pro ValueError i ZeroDivisionError, zjišťujeme přesně, jaký typ chyby byl zachycen, a vypisujeme další, specifickou zprávu. Pokud kód znovu otestujeme, měli bychom vidět i tyto další, konkrétnější zprávy pro jednotlivé zachycené výjimky.

Kdy je vhodné řešit více výjimek?

Obecně je zpracování více výjimek ideální, pokud chcete provést stejný kód pro podobné výjimky, které mohou nastat. Mezi takové situace patří například:

  • Síťové požadavky, které selhaly z různých důvodů. Bez ohledu na konkrétní příčinu můžete uživatele informovat o nedostupnosti serveru.
  • Selhání připojení k databázi, které může způsobit různé chyby. I když se tyto chyby mohou lišit, jejich zpracování může být stejné.
  • Vstupně-výstupní operace se soubory, které mohou generovat chyby, jako jsou nedostatečná oprávnění nebo plný disk, které se mohou ošetřit podobným způsobem.

Závěr

V tomto článku jsme si ukázali, jak kombinovat více bloků except do jednoho, a to zachycením více výjimek najednou. Díky tomu bude váš kód čitelnější a udržovatelnější. Pokud vás zajímají další tipy, můžete si přečíst článek o Python projektech pro začátečníky.