.. include:: markup.rst ****************** Ausnahmebehandlung ****************** Eine Ausnahme (exception) ist eine Ausnahmesituation (Fehler), die sich während der Ausführung eines Programmes einstellt. * Lässt man diese zu, so :mark:`stürzt das Programm ab!` * Fängt man diese ab (Ausnahmebehandlung), :mark:`läuft das Programm weiter!` Viele Programmiersprachen so wie :mark:`C++, PHP, Java und Python besitzen` integrierte :mark:`Mechanismen` für die Fehlerbehandlung Ausnahmebehandlung in Python ============================ Schauen wir folgendes einfache :mark:`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 "", line 1, in n = int(input("Please enter a number: ")) ValueError: invalid literal for int() with base 10: 'x' Das :mark:`Programm stoppt` was sehr unangenehm ist, sofern bereits viele manuelle Eingaben erfolgt sind! Mit Hilfe des :mark:`Ausnahmebehandlung` würde diese Eingabe wie folgt aussehen (``ausnahme_try_except.py``): .. literalinclude:: src/ausnahme_try_except.py 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`: .. table:: 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. ================= ======================================================================== 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``): .. literalinclude:: src/ausnahme_try_except_except.py .. note:: Die ``raise`` Anweisung gibt eine detaillierte Fehlermeldung aus und stoppt das Programm! Else Anweisung ============== Beim lesen von Files kann eine ``try..except`` Anweisung mit einem ``else`` Block hilfreich sein(``ausnahme_try_except_else.py``): .. literalinclude:: src/ausnahme_try_except_else.py D.h. sofern das File erfolgreich geöffnet wurde, wird im ``else`` Anweisungsblock eingelesen. Ü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. 2. 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. 3. 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.