8. Exception handling

Abgesehen von Syntaxfehlern gibt es in Python noch eine andere Art von Fehlern: die Exceptions. Das sind Fehler, die direkt im Programm abgefangen werden können. Ein Beispiel dafür ist eine Division durch Null, was einen ZeroDivisionError verursacht.

Das Python-Exceptionhandling ähnelt sehr seinem Pendant in Java. Der möglicherweise eine Exception verursachende Code wird in einen try-Block eingeschlossen, danach kann man mit except FooError-Blöcken beliebige Fehler abfangen und behandeln. Optional kann ein else-Zweig folgen, der durchlaufen wird, wenn im try-Block keine Exception auftritt.
Anstatt der except-Statements ist auch ein finally-Teil möglich, der in jedem Fall nach den anderen Blöcken ausgeführt wird. Ist dabei eine Exception aufgetreten, wird sie nach dem finally-Teil erneut ausgelöst.

Es ist sogar erlaubt, alle möglichen Exceptions mit einem parameterlosen except abzufangen, dies wird im allgemeinen aber nicht empfohlen. Man kann Exceptions auch selbst auswerfen, indem man das raise FooError-Kommando benutzt.
Wie in anderen Sprachen auch, werden Exceptions sinnvollerweise nach außen weitergereicht, falls sie in der auslösenden Methode nicht behandelt werden.

Beispiel:
>>> def divide(m, n):
...     return m/n
...
>>> try:
...     x, y = 5, 0
...     z = divide(x, y)   # in der Funktion wird eine
                           # Division durch Null auftreten
... except ZeroDivisionError:
...     print "Division by zero!"
... except:                # fängt alle nicht behandelten
                           # Fehler ab
...     print "Unknown Error!"
...     raise              # Exception nach außen weiterreichen
... else:
...     print x, "/", y, "=", z  # nur, wenn kein Fehler auftritt
...
Division by zero!

Es gibt einige schon vordefinierte Exceptions, wie z.B. einen ValueError, der eine fehlgeschlagene Typumwandlung anzeigt, einen IOError und einen NameError, der bei Referenzierung unbekannter Bezeichner auftritt.
Manche Exceptions haben auch einen internen Wert, der beim Abfangen mit einem zweiten Parameter abgefragt werden kann, und der bei einem raise befüllt werden kann.

Beispiel:
>>> try:
...     print undefined
        # wobei undefined nicht definiert ist
... except NameError, arg:
...     print "NameError:", arg
NameError: There is no variable named 'undefined'

Andererseits sind auch selbstdefinierte Exceptions aller Art möglich.
Ein Minimalbeispiel:
>>> class CustomError:
...     value = "Error"
...     def __str__(self):
...     return `self.value`
...
>>> raise CustomError
Traceback (innermost last):
  File "<pyshell#50>", line 1, in ?
    raise CustomError
CustomError: 'Error'
 
 

Module und Packages