Middle
Ako fungujú vnorené výnimky v Pythone?
sobes.tech AI
Odpoveď od AI
Vložené výnimky, známe aj ako reťazenie výnimiek, umožňujú zachovať informácie o predchádzajúcej výnimke pri vzniku novej. To je užitočné na ladenie a pochopenie príčin chyby.
V Pythone 3 sa štandardne pri vzniku novej výnimky v bloku except alebo finally automaticky spojí pôvodná výnimka s novou.
Táto väzba sa uchováva v atribúte __cause__ novej výnimky.
Explicitné spojenie je možné vykonať pomocou kľúčového slova raise from.
# Príklad automatického spojenia
def divide(a, b):
try:
return a / b
except TypeError:
# Počas spracovania TypeError môže vzniknúť iná výnimka
# Pôvodná výnimka (TypeError) bude spojená s novou
raise ValueError("Zlý typ operandu")
try:
divide("a", 0)
except ValueError as e:
# e.__cause__ bude obsahovať TypeError
print(f"Vyskytla sa chyba: {e}")
if e.__cause__:
print(f"Vyvolané z: {e.__cause__}")
print("-" * 20)
# Príklad explicitného spojenia pomocou raise from
class CustomError(Exception):
pass
def tricky_function():
try:
# Pokus o delenie nulou, spôsobí ZeroDivisionError
result = 1 / 0
except ZeroDivisionError as original_exc:
# Vytvoríme nové výnimku a spojíme ju s pôvodnou
raise CustomError("Chyba pri výpočte") from original_exc
try:
tricky_function()
except CustomError as e:
# e.__cause__ bude obsahovať ZeroDivisionError
print(f"Vyskytla sa chyba: {e}")
if e.__cause__:
print(f"Vyvolané z: {e.__cause__}")
print("-" * 20)
# Skrytie spojenia pomocou raise ... from None
try:
try:
# Pôvodná výnimka
raise ValueError("Pôvodná chyba")
except ValueError:
# Počas spracovania ValueError vznikne iná výnimka,
# ale väzba je skrytá
raise TypeError("Nová chyba") from None
except TypeError as e:
# e.__cause__ tu bude None
print(f"Vyskytla sa chyba: {e}")
if e.__cause__ is None:
print("Príčina nie je uvedená.")
Kľúčové slovo raise bez argumentov opäť vyvolá posledný výnimku.
# Príklad opätovného vyvolania výnimky
def process_data(data):
try:
# Predpokladajme, že tu môže dôjsť k chybe
if not data:
raise ValueError("Chýbajúce údaje")
print("Údaje spracované")
except ValueError:
print("Zachytili sme ValueError")
# Opätovne vyvoláme tú istú výnimku
raise
try:
process_data("")
except ValueError as e:
print(f"Zachytili sme opätovne vyvolanú výnimku: {e}")
Vnorené výnimky zlepšujú čitateľnosť trasovania chýb a pomáhajú rýchlejšie lokalizovať pôvodný problém.