W3docs

Python Try...Except

Python try, except, else und finally mit klaren Beispielen. Behandle ZeroDivisionError, ValueError, FileNotFoundError und mehr.

Wenn Python zur Laufzeit auf einen Fehler stößt, löst es eine Ausnahme (Exception) aus — ein Objekt, das beschreibt, was schiefgelaufen ist. Ohne Behandlung beendet eine Ausnahme das Programm sofort. Die try...except-Anweisung ermöglicht es, solche Ausnahmen abzufangen, angemessen darauf zu reagieren und das Programm am Laufen zu halten.

Dieses Kapitel behandelt:

  • Den try / except-Block — eine bestimmte Ausnahme abfangen
  • Ausnahmedetails mit as erfassen
  • Mehrere except-Klauseln und das gleichzeitige Abfangen mehrerer Ausnahmen
  • Den else-Block — Code, der nur ausgeführt wird, wenn keine Ausnahme auftritt
  • Den finally-Block — Bereinigungscode, der immer ausgeführt wird
  • Häufige eingebaute Ausnahmen und wann sie auftreten
  • Ausnahmen erneut auslösen
  • Best Practices und häufige Fehler

Der grundlegende try...except-Block

Umschließe den Code, der möglicherweise fehlschlägt, mit einem try-Block. Wenn Python eine Ausnahme auslöst, springt die Ausführung zum passenden except-Block, anstatt abzustürzen.

python— editable, runs on the server

Ausgabe:

Error: division by zero

Python versucht die Division, löst ZeroDivisionError aus, und der except-Block behandelt dies. Die as e-Klausel bindet das Ausnahmeobjekt an e, sodass du die Nachricht untersuchen oder protokollieren kannst.

Wenn der try-Block erfolgreich ist, wird der except-Block vollständig übersprungen.

Eine bestimmte Ausnahme abfangen

Benenne immer den Ausnahmetyp, den du erwartest. Das Abfangen eines benannten Typs macht deine Absicht klar und verhindert, dass unbeabsichtigt unzusammenhängende Fehler verborgen werden.

try:
    number = int("abc")
except ValueError as e:
    print(f"Could not convert: {e}")

Ausgabe:

Could not convert: invalid literal for int() with base 10: 'abc'

int("abc") löst ValueError aus, weil "abc" keine gültige ganze Zahl ist. Das Angeben von ValueError in der except-Klausel bedeutet, dass jede andere unerwartete Ausnahme weiterhin propagiert wird und als Fehler sichtbar bleibt, anstatt still verschluckt zu werden.

Mehrere except-Klauseln

Ein einzelner try-Block kann mehrere except-Klauseln haben — Python prüft sie von oben nach unten und führt die erste Übereinstimmung aus.

def safe_index(items, index):
    try:
        return items[index]
    except IndexError:
        print("Index out of range.")
    except TypeError:
        print("Index must be an integer.")

safe_index([1, 2, 3], 10)   # IndexError
safe_index([1, 2, 3], "a")  # TypeError

Ausgabe:

Index out of range.
Index must be an integer.

Die Reihenfolge ist wichtig: Platziere spezifischere Ausnahmetypen vor allgemeineren, damit der spezifische Handler zuerst ausgeführt wird.

Mehrere Ausnahmen in einer Klausel abfangen

Wenn zwei oder mehr Ausnahmen die gleiche Reaktion erfordern, gruppiere sie in einem Tupel:

try:
    value = int("not-a-number")
except (ValueError, TypeError) as e:
    print(f"Input error: {e}")

Ausgabe:

Input error: invalid literal for int() with base 10: 'not-a-number'

Der else-Block

Der else-Block wird nur ausgeführt, wenn der try-Block ohne das Auslösen einer Ausnahme abgeschlossen wird. Verwende ihn für Code, der bei Erfolg ausgeführt werden soll, aber selbst keinen Fehler­schutz benötigt:

try:
    result = 10 / 2
except ZeroDivisionError:
    print("Cannot divide by zero.")
else:
    print(f"Division succeeded. Result: {result}")

Ausgabe:

Division succeeded. Result: 5.0

Die Erfolgslogik im else-Block zu halten (statt am Ende des try) verhindert das unbeabsichtigte Abfangen von Ausnahmen, die der Erfolgspfad-Code selbst auslösen könnte.

Der finally-Block

Der finally-Block wird unabhängig davon ausgeführt, was passiert — ob der try-Block erfolgreich ist, eine Ausnahme abgefangen wird oder eine Ausnahme unbehandelt propagiert. Verwende ihn für die Bereinigung: Dateien schließen, Sperren freigeben oder die Verbindung zu einer Datenbank trennen.

try:
    result = 10 / 0
except ZeroDivisionError:
    print("Error caught.")
finally:
    print("This always runs — cleanup goes here.")

Ausgabe:

Error caught.
This always runs — cleanup goes here.

Auch wenn du den except-Block auskommentierst, wird finally noch ausgeführt, bevor Python die Ausnahme weitergibt.

Vollständige Struktur auf einen Blick

try:
    # code that may raise an exception
except SomeException as e:
    # handle the exception
except (AnotherError, YetAnother):
    # handle either of these
else:
    # runs only when try succeeded
finally:
    # always runs

Häufige eingebaute Ausnahmen

AusnahmeWann sie auftritt
ZeroDivisionErrorDivision oder Modulo durch null
ValueErrorRichtiger Typ, falscher Wert (z. B. int("abc"))
TypeErrorOperation auf falschen Typ angewendet
IndexErrorSequenzindex außerhalb des Bereichs
KeyErrorDictionary-Schlüssel nicht gefunden
FileNotFoundErrorDatei oder Verzeichnis existiert nicht
AttributeErrorObjekt hat kein solches Attribut
ImportErrorModul kann nicht importiert werden
NameErrorVariablenname ist nicht definiert

Alle diese erben von der Basisklasse Exception. Du kannst Exception abfangen, um alle davon in einer Klausel zu behandeln, aber bevorzuge nach Möglichkeit spezifische Typen.

Eine fehlende Datei behandeln

try:
    with open("data.txt", "r") as file:
        content = file.read()
except FileNotFoundError:
    print("Error: File not found.")

Ausgabe (wenn data.txt nicht existiert):

Error: File not found.

Eine Ausnahme erneut auslösen

Manchmal möchtest du eine Ausnahme protokollieren oder eine teilweise Bereinigung durchführen, sie aber dennoch zum Aufrufer propagieren lassen. Verwende ein bloßes raise innerhalb eines except-Blocks:

def process():
    try:
        result = 10 / 0
    except ZeroDivisionError:
        print("Logging error...")
        raise  # re-raises the original ZeroDivisionError

try:
    process()
except ZeroDivisionError as e:
    print(f"Outer handler caught: {e}")

Ausgabe:

Logging error...
Outer handler caught: division by zero

Das bloße raise bewahrt den ursprünglichen Traceback, sodass das Debuggen nicht schwieriger wird als ohne den Handler.

Die Basisklasse Exception abfangen

Du kannst Exception als Auffangbecken für jeden nicht-system­beendenden Fehler verwenden:

try:
    result = 10 / 0
except Exception as e:
    print(f"An error occurred: {type(e).__name__}: {e}")

Ausgabe:

An error occurred: ZeroDivisionError: division by zero

type(e).__name__ liefert den spezifischen Klassennamen, auch wenn du über die Basisklasse abfängst. Das ist nützlich in Top-Level-Handlern, wo du jeden unerwarteten Fehler protokollieren möchtest.

Bare except — und warum man es vermeiden sollte

Ein bare except (ohne Ausnahmetyp) fängt buchstäblich alles ab, einschließlich KeyboardInterrupt (Strg+C) und SystemExit, was es schwer macht, dein Programm zu unterbrechen:

# Avoid this pattern
try:
    result = 10 / 0
except:
    print("Some error occurred")

Bevorzuge except Exception, wenn du ein breites Netz benötigst, da es KeyboardInterrupt und SystemExit weiterhin normal propagieren lässt.

Best Practices

  • Sei spezifisch. Fange den engsten Ausnahmetyp ab, der sinnvoll ist.
  • Unterdrücke keine Ausnahmen. Protokolliere mindestens den Fehler; lasse einen except-Block niemals leer.
  • Verwende else für Erfolgspfad-Code. Dadurch bleibt der try-Block so klein wie möglich.
  • Verwende finally für die Bereinigung. Oder, noch besser, verwende eine with-Anweisung — siehe Python with Statement.
  • Vermeide bare except. Verwende except Exception, wenn du ein breites Netz benötigst.
  • Löse bei Bedarf erneut aus. Wenn du den Fehler nicht vollständig behandeln kannst, lass ihn mit raise propagieren.

Informationen zum absichtlichen Auslösen von Ausnahmen und zum Erstellen eigener Ausnahmeklassen findest du unter Python raise and Custom Exceptions.

Übungen

Übung
What is the functionality of 'Try' and 'Except' in Python?
What is the functionality of 'Try' and 'Except' in Python?
Was this page helpful?