9. Ausnahmebehandlung

Eine Ausnahme (exception) ist eine Ausnahmesituation (Fehler), die sich während der Ausführung eines Programmes einstellt.

  • Lässt man diese zu, so stürzt das Programm ab!
  • Fängt man diese ab (Ausnahmebehandlung), läuft das Programm weiter!

Viele Programmiersprachen so wie C++, PHP, Java und Python besitzen integrierte Mechanismen für die Fehlerbehandlung

9.1. Ausnahmebehandlung in Python

Schauen wir folgendes einfache Beispiel an. Ein Benutzer soll einen integer Wert angeben, vertippt sich aber:

In [1]: n = int(input("Please enter a number: "))

Please enter a number: x
Traceback (most recent call last):

  File "<ipython-input-12-02fbe8840e1a>", line 1, in <module>
    n = int(input("Please enter a number: "))

ValueError: invalid literal for int() with base 10: 'x'

Das Programm stoppt was sehr unangenehm ist, sofern bereits viele manuelle Eingaben erfolgt sind!

Mit Hilfe des Ausnahmebehandlung würde diese Eingabe wie folgt aussehen (ausnahme_try_except.py):

while True:
   try:
      n = input("Bitte eine Ganzzahl (integer) eingeben: ")
      n = int(n)
      break
   except ValueError:
      print("Keine Integer! Bitte nochmals versuchen ...")
print("Super! Das war's!")

mit folgender Ein- Ausgabe:

Bitte eine Ganzzahl (integer) eingeben: x
Keine Integer! Bitte nochmals versuchen ...

Bitte eine Ganzzahl (integer) eingeben: 1
Super! Das war's!

Der try..except Block fängt dabei Fehler ab ohne das Programm zu stoppen.

Es gibt eine Reihe vordefinierter Fehler. Ein Auszug findet sich in Tabelle Standard-Ausnahmen.

Standard Ausnahmen
Exeption Beschreibung
ImportError import Statement findet das angegeben Modul nicht
IndexError Tritt auf wenn Index bei einer Sequenz nicht existiert
IOError Entsteht wenn Ein- Ausgabe Operation misslingt (Zugriff auf Datei).
KeyError Tritt auf wenn Key bei einem Dictionary nicht existiert
NameError Wird erzeugt wenn Name im Namensraum nicht existiert.
SyntaxError Tritt bei Synthaxfehlern auf.
TypeError Entsteht wenn Operator auf Objekt ungeeigneten Typs angewendet wird.
ZeroDivisionError Tritt bei Divisionen durch null auf.

9.2. Mehrere Ausnahme-Blöcke

Zu einem try-Block können mehrere except-Blöcke gehören. Aber nur einer wird ausgeführt!

Beispiel (ausnahme_try_except_except.py):

try:
    f = open('exception2.txt')
    s = f.readline()
    i = int(s.strip())
except IOError:
    print("I/O error")                  # schreibt Meldung, macht weiter
except ValueError:
    print("No valid integer in line.")  # schreibt Meldung, macht weiter
except:
    print("Unexpected error:")          # schreibt Meldung
    raise                               # wirft genaue Fehlermeldung aus

print("Alles gut gegangen?")

Bemerkung

Die raise Anweisung gibt eine detaillierte Fehlermeldung aus und stoppt das Programm!

9.3. Else Anweisung

Beim lesen von Files kann eine try..except Anweisung mit einem else Block hilfreich sein(ausnahme_try_except_else.py):

file_name = "woerterbuch.txt"
text = []
try:
   fh = open(file_name, 'r')
except IOError:
   print("ERROR: cannot open", file_name)
else:
   text = fh.readlines()
   print("OK", text)
   fh.close()

D.h. sofern das File erfolgreich geöffnet wurde, wird im else Anweisungsblock eingelesen.

9.4. Übungsbeispiele

Aufgabe 9.1

Gehen Sie von Ihrer Lösung für die Aufgabe 8.1 (Klasse Vektor) aus.

  1. Versuchen Sie im Abschnitt main die folgenden Objekte zu addieren:

    Vektor1 = Vektor([1,2])
    Vektor2 = Vektor([1,2,3])
    Vektor1+Vektor2
    Vektor2+Vektor1
    
Welche Art von Fehler tritt auf? Fangen Sie den auftretenden Fehler im überladenen add-Operator gezielt mit Hilfe eines try-except Blockes ab. Lassen Sie im except Block eine hilfreiche Fehlermeldung ausgeben und geben Sie False zurück.
  1. Versuchen Sie nun im Abschnitt main die folgenden Objekte zu addieren:

    Vektor1 = Vektor([1,2])
    Vektor2 = Vektor([1,"Orange"])
    Vektor1+Vektor2
    
Welche Art von Fehler tritt auf? Fangen Sie den auftretenden Fehler im überladenen add-Operator gezielt mit Hilfe eines try-except Blockes ab. Lassen Sie im except Block eine hilfreiche Fehlermeldung ausgeben und geben Sie False zurück.
  1. Verhindern Sie mittels einer raise TypeError Anweisung im Konstruktor, dass die Klasse Vektor mit einer Liste, die etwas anderes als Zahlen (float oder int) enthält, initialisiert werden kann.

Aufgabe 9.2

Gehen Sie von der Lösung von Aufgabe 5.1 aus. Versuchen Sie folgende Fehler in der Funktion berechne_Distanz(A,B) abzufangen:

  1. Die Listen könnten eine unterschiedliche Anzahl von Einträgen haben, z.B.:

    A = [1,2,3]
    B = [1,2]
    Distanz = berechne_Distanz(A,B)
    

    Bestimmen Sie den Fehlertyp und fangen Sie den Fehler mittels try-except Block in der Funktion ab. Tritt diese Fehler auf, soll eine Fehlermeldung ausgebeben und der Wert -1 zurückgeben werden.

  2. Statt einer Liste könnte ein falscher Datentyp übergeben werden, z.B.:

    A = [1,2,3]
    B = "unbekannt"
    Distanz = berechne_Distanz(A,B)
    

    Bestimmen Sie den Fehlertyp und fangen Sie den Fehler mittels try-except Block in der Funktion ab. Tritt diese Fehler auf, soll eine Fehlermeldung ausgebeben und der Wert -2 zurückgeben werden.