Python3 – Teil 6 Fehlerhandling

Erwartete Lesezeit: 4 minuten

In diesem Beitrag gehen wir kurz auf das Fehlerhandling in Python ein.

Syntaxfehler

Die einfachsten Fehler sind die Syntaxfehler , die bei der Umwandlung des Sourcecodes im Zuge der Interpretation des Codes auftreten kann. Je nach IDE werden diese bereits im Editor oder erst bei der Ausführung des Codes sichtbar.
Im folgendem Codeblock habe ich mal einen kleinen – aber beliebten – Fehler eingebaut.

tiere = {'Hund':'Canis','Katze':'feles','Maus':'Mus'}
for deutsch, latein in tiere.items()
    print('Der lateinische Name für ' + deutsch + ' ist ' + latein)

Beim Ausführen kommt die folgende Meldung

 File "E:\IntelliJProjecte\sorter\Schulung.py", line 4
    for deutsch, latein in tiere.items()
                                        ^
SyntaxError: invalid syntax

Der Interpretor sagt einem die Zeilennummer und die Stellle , an der der Fehler vermuted wird. Im Beispiel hier fehlt der Doppelpunkt hinter ..items() .

Exceptions

Auch in syntaxkorrektem Code können Fehler auftreten. Sei es eine Division durch 0 , die Nutzung von nicht initialisierten Variablen,….
Eine Übersicht über die in Python eingebauten Exceptions findet Ihr in der offiziellen Dokumentation unter https://docs.python.org/3/library/exceptions.html#bltin-exceptions . Auf diese gehe ich hier nicht genauer ein.

Viel interessanter ist die Erzeugung eigener Exceptions.

Die Objektorientierte Programmierung kommt in einem späteren Beitrag genauer , aber für die eigenen Exceptions müssen wir uns jetzt schonmal mit Klassen und Vererbung befassen. Per Definition ist eine Klasse:

Eine Klasse dient als Bauplan für die Abbildung von realen Objekten in Softwareobjekte und beschreibt Attribute (Eigenschaften) und Methoden (Verhaltensweisen) der Objekte.

https://de.wikipedia.org/wiki/Klasse_(Objektorientierung)#:~:text=Unter%20einer%20Klasse%20(auch%20Objekttyp,Programmierung%20ein%20abstraktes%20Modell%20bzw.&text=Die%20Klasse%20dient%20als%20Bauplan,Methoden%20(Verhaltensweisen)%20der%20Objekte.

Vererbung bedeutete kurz gesagt , dass man innerhalt einer Klasse von einem Bauplan einer Klasse profitieren kann. Wie gesagt, mehr in einem weiteren Beitrag.

Für unsere eigene Exception müssen wir uns nun eine Klasse bauen , die von der Exception Klassen die Funktionen erbt. Wir bauen uns nun eine Exception die bei der Validierung einer EMail-Adresse auftreten könnte. Gemäß der allgemeinen Programmierrichtlinien sollten die Fehlerklassen mit Error enden.

class EMailvalidationError(Exception):
    """ Error occuring during valiadtion of email """
    def __init__(self, expression, message):
        self.expression = expression
        self.message = message

Mehr Code ist nicht notwendig. Zur Erklärung :
Zeile 1 wird die Klasse EMailvalidationError deklariert und die Vererbung von der Klassen Exception festgelegt.
Zeile 2 ist die Dokumentation der Klasse (Analog Java-Doc, in Python wird die Doku nicht vor die Zeile geschrieben , sondern danach und durch die drei doppelten Hochkommantas hinterlegt.
Zeile 3-5 ist der Konstruktor der Klasse der Werte Expression und Message erhält. Diese werden über self an die Klasse Exception weitergegeben. (Grob erklärt)

Wie nutzt (wirft) man nun die Exception. Da unsere Exception im Zuge der EMail-Validierung geworfen werden soll. Hierzu nutzen wir den Befehl raise <Exception>

email ='text$example.org'
if email.find('@') == -1:
    raise EMailvalidationError('@','missing')

Da in unserer E-Mailadresse das @ Zeichen fehlt, erscheint die folgende Meldung:

Traceback (most recent call last):
  File "E:\IntelliJProjecte\sorter\Schulung.py", line 9, in <module>
    raise EMailvalidationError('@','missing')
__main__.EMailvalidationError: ('@', 'missing')

Zu Testzwecken ok , aber in produktiven Anwendungen wäre eine sprechende Fehlermeldung natürlich für den Anwender schöner. Also benötigen wir ein Exceptionhandling.

Wie in vielen anderen Sprachen können wir einen Try Catch Block nehmen , nur mit dem Unterschied, dass in Python das “Catch” “except” heißt. Für unser Beispiel könnte das ganze wie folgt aussehen :

try:
  self.checkEMail(emailadresse)
except EMailvalidationError:
  print('Fehler')
else: 
  print('Email ok')
finally: 
  print('Egal was passiert ist , dieses wird immer ausgegeben')

Über try wird gesagt , was probiert werden / ausgeführt werden soll.
except fängt einen Error ab und ermöglicht eine fehlerspezifische Fehlerbehandlung.
Else (optional) ermöglicht Code auszuführen , wenn alles ok ist.
finally Dieser Code wird immer ausgeführt, egal ob eine Exception aufgetreten ist oder nicht.