Exceptions#

In diesem Abschnitt geht es um Ausnahmen, d.h. um Sprachfunktionen, die speziell ungewöhnliche Umstände während der Ausführung eines Programms behandeln. Die häufigste Ausnahme ist die Behandlung von Fehlern, aber sie können auch für viele andere Zwecke effektiv eingesetzt werden. Python bietet einen umfassenden Satz von Ausnahmen, und ihr könnt neue Ausnahmen für eure eigenen Zwecke definieren.

Der gesamte Exception-Mechanismus in Python ist objektorientiert: Eine Exception ist ein Objekt, das automatisch von Python-Funktionen mit einer raise-Anweisung erzeugt wird. Diese raise-Anweisung veranlasst die Ausführung des Python-Programms auf eine andere Art und Weise, als üblicherweise vorgesehen: Die aktuelle Aufrufkette wird nach einem Handler durchsucht, der die erzeugte Ausnahme behandeln kann. Wenn ein solcher Handler gefunden wird, wird er aufgerufen und kann auf das Ausnahmeobjekt zugreifen, um weitere Informationen zu erhalten. Wird kein geeigneter Exception-Handler gefunden, bricht das Programm mit einer Fehlermeldung ab.

Es ist möglich, verschiedene Arten von Ausnahmen zu erzeugen, um die tatsächliche Ursache des gemeldeten Fehlers oder außergewöhnlichen Umstandes zu reflektieren. Eine Übersicht über die Klassenhierarchie eingebauter Exceptions erhaltet ihr unter Exception hierarchy in der Python-Dokumentation. Jeder Ausnahmetyp ist eine Python-Klasse, die von ihrem übergeordneten Exception-Typ erbt. So ist z.B. (zum Beispiel ein ZeroDivisionError durch Vererbung auch ein ArithmeticError, eine Exception und auch eine BaseException. Diese Hierarchie ist gewollt: Die meisten Ausnahmen erben von Exception, und es wird dringend empfohlen, dass alle benutzerdefinierten Ausnahmen auch die Unterklasse von Exception und nicht von BaseException bilden:

1class EmptyFileError(Exception):
2    pass

Dies definiert ihr euren eigenen Ausnahmetyp, der vom Basistyp Exception erbt.

5filenames = ["myFile1.py", "nonExistent.py", "emptyFile.py", "myFile2.py"]

Eine Liste unterschiedlicher Datei-Arten wird definiert.

Schließlich werden Ausnahmen oder Fehler mit Hilfe der zusammengesetzten Anweisung try-except-else-finally abgefangen und behandelt. Jede Ausnahme, die nicht abgefangen wird, führt zur Beendigung des Programms.

 7for file in filenames:
 8    try:
 9        f = open(file, "r")
10        line = f.readline()
11        if line == "":
12            raise EmptyFileError(f"{file} is empty")
13    except OSError as error:
14        print(f"Cannot open file {file}: {error.strerror}")
15    except EmptyFileError as error:
16        print(error)
17    else:
18        print(f"{file}: {f.readline()}")
19    finally:
20        print("File", file, "processed")
21        f.close()
Zeile 7

Wenn während der Ausführung der Anweisungen im try-Block ein OSError oder EmptyFileError auftritt, wird der zugehörige except-Block ausgeführt.

Zeile 9

Hier könnte ein OSError ausgelöst werden.

Zeile 12

Hier löst ihr den EmptyFileError aus.

Zeile 17

Die else-Klausel ist optional; sie wird ausgeführt, wenn im try-Block keine Ausnahme auftritt.

Bemerkung

In diesem Beispiel hätte stattdessen auch continue-Anweisungen in den except-Blöcken verwendet werden können.

Zeile 19

Die finally-Klausel ist optional; sie wird am Ende des Blocks ausgeführt, unabhängig davon, ob eine Ausnahme ausgelöst wurde oder nicht.