In Python wird die Ausnahmebehandlung durch die Konstruktionen try/except/else/finally und den Operator raise realisiert.
try definiert den geschützten Codeblock. Wenn innerhalb dieses Blocks eine Ausnahme auftritt, wird die Kontrolle an den nächsten geeigneten except-Block übergeben. Wenn keine Ausnahme auftritt, wird der block else, falls vorhanden, ausgeführt. Der Block finally wird immer ausgeführt – unabhängig davon, ob eine Ausnahme aufgetreten ist oder nicht (zum Beispiel zum Freigeben von Ressourcen).
Der Operator raise löst eine Ausnahme explizit oder wiederholt die aktuelle (im except-Block ohne Angabe des Typs).
Beispiel:
try: x = 1 / 0 except ZeroDivisionError as e: print(f"Fehler: {e}") else: print("Es gab keinen Fehler") finally: print("Wird immer ausgeführt")
Ausgabe:
Fehler: division by zero
Wird immer ausgeführt
Feinheiten:
Frage: „Was passiert, wenn sowohl im Block try als auch im finally unterschiedliche Ausnahmen mit raise ausgelöst werden?“
Antwort: Die Ausnahme aus finally "überschreibt" die Ausnahme aus try: nach außen geht das heraus, was im finally ausgelöst wurde.
def foo(): try: raise ValueError("im try") finally: raise IndexError("im finally") try: foo() except Exception as e: print(repr(e)) # Gibt aus: IndexError('im finally')
Geschichte
Im ETL-Prozess wurde im finally bedingungslos die Verbindung zur Datenbank geschlossen, aber es wurde vergessen, dass dabei im finally eine Ausnahme auftreten kann (zum Beispiel, wenn die Verbindung bereits geschlossen ist). Ergebnis – eine "versteckte" Ausnahme aus finally hat die Ausnahme aus dem Hauptcode vollständig absorbiert, was das Debugging erheblich erschwerte.
Geschichte
Es wurden Ketten mehrerer excepts verwendet: von allgemeinem except Exception über spezifischen. Infolgedessen blieben alle spezifischen excepts "tot" – niedrigstufige Ausnahmen wurden nicht einzeln gefangen, was die Behandlung spezifischer Fehler erschwerte.
Geschichte
In einem Webdienst wurde im except-Block vergessen, die Ausnahme über "raise" weiterzuleiten, während der Fehler protokolliert wurde, aber die Ausführung weiterging. Infolgedessen gingen reale Fehler "verloren", und das Programm arbeitete weiterhin mit einem inkorrekten Zustand.