- 1 Section
- 10 Lessons
- unbegrenzt
- Python Grundlagen10
- 1.1Python-Grundlagen: Installation, REPL, erstes Skript
- 1.2Variablen, Datentypen, Typumwandlung
- 1.3Kontrollstrukturen: if, elif, else
- 1.4Schleifen: for, while, range
- 1.5Listen, Tupel, Dictionaries, Sets
- 1.6Funktionen: def, Parameter, return
- 1.7Fehlerbehandlung: try-except-finally
- 1.8Strings: Methoden, Formatierung, f-Strings
- 1.9Dateien lesen und schreiben
- 1.10Praxisprojekt: Kleines Python-Programm von A bis Z
Fehlerbehandlung: try-except-finally
Selbst der beste Code stürzt manchmal ab – jemand gibt „abc" ein wo eine Zahl erwartet wird, eine Datei existiert nicht, eine Internet-Verbindung bricht ab, eine Berechnung teilt durch null. Wenn dein Programm so etwas nicht abfangen kann, crasht es einfach. Genau dafür gibt es Exception Handling: ein eingebautes System um Fehler kontrolliert zu behandeln statt von ihnen überrascht zu werden.
Python folgt dabei einer eigenen Philosophie die sich von Java unterscheidet: „Es ist einfacher um Vergebung zu bitten als um Erlaubnis". Heißt: erst versuchen, dann reagieren wenn was schiefläuft. Statt vor jedem Schritt zu prüfen ob alles OK ist. Diese Haltung („EAFP" – Easier to Ask Forgiveness than Permission) ist sehr pythonic.
1) Was ist eine Exception?
Wenn etwas schiefgeht „wirft" (raise) Python eine Exception – ein spezielles Objekt das den Fehler beschreibt. Wenn nichts diese Exception abfängt, „propagiert" sie nach oben durch alle aufrufenden Funktionen bis zum Programm-Start. Dann sieht der Benutzer eine hässliche Fehlermeldung wie diese – ein sogenannter Traceback:
Tracebacks liest man von unten nach oben: ganz unten steht WAS passiert ist (ZeroDivisionError), darüber WO im Code – mit den Funktionsaufrufen die dahin geführt haben (siehe Funktionen-Lektion). Die unterste Datei/Zeile ist der eigentliche Ort des Fehlers. Wer Tracebacks fließend lesen kann, debuggt viel schneller.
2) Die wichtigsten eingebauten Exceptions
Python hat dutzende eingebaute Exception-Typen, die hierarchisch organisiert sind. Hier die wichtigsten – klicke einen Knoten für Details und ein Beispiel wann sie auftritt:
Exception ist die Basis aller „normalen" Fehler. Darunter Kategorien (ArithmeticError, LookupError, ...), darunter die konkreten Fehler. Wenn du except Exception: schreibst, fängst du ALLE diese Fehler – das ist meistens zu breit. Lieber den spezifischen Typ angeben um nicht unbeabsichtigt Programmierfehler zu schlucken.3) try-except: der Schutzring
Die Grundstruktur: Code der schiefgehen könnte packst du in einen try-Block. Was passieren soll wenn etwas schiefgeht, kommt in except. Du kannst dabei nach Exception-Typ unterscheiden:
Wenn der Benutzer „25" eingibt → alles läuft. Tippt er „abc" → int() wirft ValueError, der except-Block fängt das ab, das Programm bricht nicht ab. Du kannst auch mehrere except-Blöcke für verschiedene Fehler haben:
4) Live-Tracer: try-except in Aktion
Wähle ein Szenario und klicke dich durch um zu sehen welcher Pfad genommen wird:
5) Die Exception abfangen UND auslesen mit „as"
Wenn du den Fehler-Details brauchst (z.B. für Logging), kannst du die Exception in eine Variable schreiben:
Mehrere Exception-Typen im selben Block fangen geht mit einem Tupel:
6) Eigene Exceptions werfen mit raise
Manchmal willst du selbst einen Fehler signalisieren – etwa wenn ein Parameter nicht stimmt. Dafür gibt's raise:
Eigene Exception-Klassen erstellst du indem du von Exception erbst – mehr zu Klassen-Vererbung lernst du in K41b. Für kleine Programme reicht oft das einfache raise ValueError("...") mit einer aussagekräftigen Nachricht.
7) Pythonic: EAFP vs LBYL
Zwei Stile gegen Fehler vorzugehen:
„Easier to Ask Forgiveness than Permission" – mach es einfach und reagiere auf Fehler.
wert = d["name"]
except KeyError:
wert = "unbekannt"
„Look Before You Leap" – prüfen bevor man etwas macht.
wert = d["name"]
else:
wert = "unbekannt"
8) Wichtige Fehlerbehandlungs-Patterns
Drei Muster solltest du auswendig kennen:
| Muster | Wann? | Wie? |
|---|---|---|
| Spezifische Exceptions fangen | Eine konkrete Fehlerart erwartet | except ValueError: |
| Mehrere fangen | Verschiedene Reaktionen nötig | Mehrere except-Blöcke |
| finally für Cleanup | Ressourcen müssen freigegeben werden | finally: oder besser noch: with (siehe L9) |
| Loop bis valid | Benutzer-Eingabe wiederholt versuchen | while True + try-except + return/break |
| ❌ Bare except | Niemals (außer ganz oben in main) | except: ohne Typ fängt ALLES – sogar KeyboardInterrupt |
Zusammenfassung
Exception = Objekt das einen Fehler beschreibt. Wirft sich von selbst (oder per raise), wandert durch den Call-Stack bis abgefangen → sonst Crash mit Traceback. try-except: try: ... except Typ: .... Optional else (kein Fehler), finally (immer). Wichtigste Typen: ValueError, TypeError, KeyError, IndexError, ZeroDivisionError, FileNotFoundError, AttributeError, NameError. Fehler in Variable: except X as e:. Mehrere Typen: except (X, Y):. raise Type("msg") wirft eigenen Fehler. EAFP ist pythonic: erst versuchen, dann reagieren. Bare except niemals nutzen!
