Ausnahmen mit try except in Python behandeln

PythonBeginner
Jetzt üben

Einführung

In diesem Lab lernen Sie, wie Sie Ausnahmen (Exceptions) in Python mithilfe der try...except-Anweisung effektiv behandeln. Wir werden untersuchen, wie man spezifische Ausnahmen wie ValueError abfängt, mehrere Ausnahmetypen behandelt und die Blöcke else und finally für eine bessere Kontrolle über den Programmablauf verwendet. Sie lernen auch, wie man benutzerdefinierte Ausnahmen auslöst (raise), um spezifische Fehlerbedingungen im Code zu signalisieren. Durch praktische Übungen sammeln Sie Erfahrung im Schreiben robuster und fehlertoleranter Python-Programme.

Dies ist ein Guided Lab, das schrittweise Anweisungen bietet, um Ihnen beim Lernen und Üben zu helfen. Befolgen Sie die Anweisungen sorgfältig, um jeden Schritt abzuschließen und praktische Erfahrungen zu sammeln. Historische Daten zeigen, dass dies ein Labor der Stufe Anfänger mit einer Abschlussquote von 100% ist. Es hat eine positive Bewertungsrate von 100% von den Lernenden erhalten.

ValueError mit try except behandeln

In diesem Schritt lernen Sie, wie Sie einen ValueError mithilfe der try...except-Anweisung behandeln. Ein ValueError tritt auf, wenn eine Funktion ein Argument des korrekten Typs, aber mit einem ungeeigneten Wert erhält. Ein häufiges Beispiel ist der Versuch, eine Zeichenkette, die keine Zahl ist, mithilfe der Funktion int() in einen Integer umzuwandeln.

Wir schreiben ein Python-Skript, das den Benutzer zur Eingabe einer Ganzzahl (Integer) auffordert. Wenn die Eingabe keine gültige Ganzzahl ist, fangen wir den ValueError ab und zeigen eine benutzerfreundliche Nachricht an.

Suchen Sie im WebIDE-Dateiexplorer auf der linken Seite die Datei handle_value_error.py im Verzeichnis ~/project und öffnen Sie diese. Fügen Sie dann den folgenden Code hinzu:

while True:
    try:
        x = int(input('Please enter an integer: '))
        print(f'You entered: {x}')
        break
    except ValueError:
        print('That was not a valid integer. Please try again.')

Speichern Sie die Datei.

Öffnen Sie nun das integrierte Terminal und führen Sie das Skript mit dem Befehl python aus:

python ~/project/handle_value_error.py

Das Skript wird Sie auffordern, eine Ganzzahl einzugeben. Versuchen Sie zuerst, einen Wert einzugeben, der keine Ganzzahl ist, wie zum Beispiel hello, um die Fehlerbehandlung in Aktion zu sehen. Geben Sie anschließend eine gültige Ganzzahl wie 123 ein, um den erfolgreichen Ausführungspfad zu sehen.

Beispielausgabe:

Please enter an integer: hello
That was not a valid integer. Please try again.
Please enter an integer: 123
You entered: 123

In diesem Code:

  • Die while True:-Schleife stellt sicher, dass das Programm weiterhin nach Eingaben fragt, bis eine gültige Ganzzahl eingegeben wird.
  • Der try-Block enthält den Code, der möglicherweise eine Ausnahme auslöst, insbesondere den Aufruf int(input(...)).
  • Wenn im try-Block ein ValueError auftritt, wird der Code innerhalb des Blocks except ValueError: ausgeführt.
  • Wenn keine Ausnahme auftritt, wird die print()-Anweisung ausgeführt, und break beendet die Schleife.

Dies demonstriert, wie try...except ValueError es Ihnen ermöglicht, ungültige Eingaben elegant zu behandeln, ohne dass das Programm abstürzt.

Mehrere Ausnahmen behandeln

Ein Codeblock kann potenziell verschiedene Arten von Ausnahmen auslösen. Python ermöglicht es Ihnen, mehrere Ausnahmen zu behandeln, indem Sie entweder mehrere except-Klauseln verwenden oder Ausnahmen in einer einzigen except-Klausel gruppieren.

Schreiben wir ein Skript, das eine Division durchführt. Diese Operation kann einen ValueError auslösen, wenn die Eingabe keine Zahl ist, und einen ZeroDivisionError, wenn der Divisor Null ist.

Öffnen Sie in der WebIDE die Datei ~/project/handle_multiple_exceptions.py und fügen Sie den folgenden Code hinzu. Diese Version verwendet separate except-Blöcke für jeden Fehlertyp.

try:
    numerator = int(input("Enter the numerator: "))
    denominator = int(input("Enter the denominator: "))
    result = numerator / denominator
    print(f"Result: {result}")
except ValueError:
    print("Invalid input. Please enter integers only.")
except ZeroDivisionError:
    print("Error: Division by zero is not allowed.")

Speichern Sie die Datei und führen Sie sie im Terminal aus:

python ~/project/handle_multiple_exceptions.py

Testen Sie das Skript mit verschiedenen Eingaben, um jede Ausnahme auszulösen:

  1. Geben Sie einen Wert ein, der keine Ganzzahl ist (z. B. abc).
  2. Geben Sie 0 für den Nenner ein.
  3. Geben Sie für beide gültige Ganzzahlen ein.

Beispielausgabe für Division durch Null:

Enter the numerator: 10
Enter the denominator: 0
Error: Division by zero is not allowed.

Sie können mehrere Ausnahmen auch mit einer einzigen except-Klausel behandeln, indem Sie sie in einem Tupel gruppieren. Dies ist nützlich, um für verschiedene Fehler die gleiche Aktion durchzuführen.

Aktualisieren Sie nun den Code in ~/project/handle_multiple_exceptions.py, um diesen gruppierten Ansatz zu verwenden:

try:
    numerator = int(input("Enter the numerator: "))
    denominator = int(input("Enter the denominator: "))
    result = numerator / denominator
    print(f"Result: {result}")
except (ValueError, ZeroDivisionError):
    print("An error occurred: Invalid input or division by zero.")

Speichern Sie die Datei und führen Sie sie erneut mit denselben Testfällen aus, um die neue, kombinierte Fehlermeldung zu beobachten.

Code mit der else-Klausel ausführen

Die try-Anweisung kann eine optionale else-Klausel enthalten. Der Code im else-Block wird nur ausgeführt, wenn der try-Block abgeschlossen wird, ohne eine Ausnahme auszulösen. Dies ist nützlich, um den Code, der bei Erfolg ausgeführt werden soll, vom Hauptteil des try-Blocks zu trennen.

Modifizieren wir unser Divisionsskript, um einen else-Block einzuschließen.

Öffnen Sie in der WebIDE die Datei ~/project/try_except_else.py und fügen Sie den folgenden Code hinzu:

try:
    numerator = int(input("Enter the numerator: "))
    denominator = int(input("Enter the denominator: "))
    result = numerator / denominator
except (ValueError, ZeroDivisionError):
    print("An error occurred: Invalid input or division by zero.")
else:
    print("Division successful!")
    print(f"Result: {result}")

Speichern Sie die Datei und führen Sie sie im Terminal aus:

python ~/project/try_except_else.py

Testen Sie das Skript sowohl mit fehlschlagenden als auch mit erfolgreichen Eingaben:

  1. Geben Sie 0 für den Nenner ein, um eine Ausnahme auszulösen.
  2. Geben Sie gültige, von Null verschiedene Ganzzahlen ein, um den else-Block auszuführen.

Beispielausgaben:

Enter the numerator: 10
Enter the denominator: 0
An error occurred: Invalid input or division by zero.
Enter the numerator: 10
Enter the denominator: 2
Division successful!
Result: 5.0

Wie Sie sehen, werden die Meldungen im else-Block nur gedruckt, wenn die Division erfolgreich war. Wenn eine Ausnahme auftritt, wird der except-Block ausgeführt und der else-Block übersprungen.

Codeausführung mit der finally-Klausel sicherstellen

Die try-Anweisung verfügt außerdem über eine optionale finally-Klausel. Der Code innerhalb des finally-Blocks wird immer ausgeführt, unabhängig davon, ob im try-Block eine Ausnahme aufgetreten ist oder nicht. Dies macht ihn ideal für Aufräumarbeiten (Cleanup actions), wie das Schließen von Dateien oder das Freigeben von Ressourcen, die in jedem Szenario stattfinden müssen.

Fügen wir unserem Divisionsbeispiel einen finally-Block hinzu.

Öffnen Sie in der WebIDE die Datei ~/project/try_except_finally.py und fügen Sie den folgenden Code hinzu:

try:
    numerator = int(input("Enter the numerator: "))
    denominator = int(input("Enter the denominator: "))
    result = numerator / denominator
    print(f"Result: {result}")
except (ValueError, ZeroDivisionError):
    print("An error occurred: Invalid input or division by zero.")
finally:
    print("Execution finished.")

Speichern Sie die Datei und führen Sie sie im Terminal aus:

python ~/project/try_except_finally.py

Führen Sie das Skript sowohl mit fehlschlagenden als auch mit erfolgreichen Eingaben aus:

  1. Geben Sie 0 für den Nenner ein, um eine Ausnahme auszulösen.
  2. Geben Sie gültige, von Null verschiedene Ganzzahlen ein.

Beispielausgaben:

Enter the numerator: 10
Enter the denominator: 0
An error occurred: Invalid input or division by zero.
Execution finished.
Enter the numerator: 10
Enter the denominator: 2
Result: 5.0
Execution finished.

Beachten Sie, dass die Meldung "Execution finished." aus dem finally-Block in beiden Fällen gedruckt wird. Es ist garantiert, dass der finally-Block ausgeführt wird, was ihn zu einem zuverlässigen Ort für notwendigen Aufräumcode macht.

Benutzerdefinierte Ausnahmen auslösen

Manchmal müssen Sie einen Fehlerzustand signalisieren, der keine eingebaute Python-Ausnahme ist. Dies können Sie mit der raise-Anweisung tun, mit der Sie Ihre eigenen Ausnahmen erstellen und auslösen können. Dies ist nützlich, um die Fehlerbehandlung Ihrer Anwendung spezifischer und aussagekräftiger zu gestalten.

Sehen wir uns zunächst an, wie man eine eingebaute Ausnahme auslöst (raise). Öffnen Sie in der WebIDE die Datei ~/project/raise_exception.py und fügen Sie den folgenden Code hinzu:

def check_positive(number):
    if number <= 0:
        raise ValueError("Input must be a positive number")
    print(f"The number {number} is positive.")

try:
    check_positive(-5)
except ValueError as e:
    print(f"Caught an exception: {e}")

try:
    check_positive(10)
except ValueError as e:
    print(f"Caught an exception: {e}")

Speichern Sie die Datei und führen Sie sie im Terminal aus:

python ~/project/raise_exception.py

Die Ausgabe wird sein:

Caught an exception: Input must be a positive number
The number 10 is positive.

Hier löst die Funktion check_positive einen ValueError aus, wenn die Eingabe nicht positiv ist, welcher dann vom except-Block abgefangen wird.

Nun definieren und lösen wir eine benutzerdefinierte Ausnahme aus (Custom Exception). Benutzerdefinierte Ausnahmen sind Klassen, die von der eingebauten Exception-Klasse erben.

Öffnen Sie in der WebIDE die Datei ~/project/custom_exception.py und fügen Sie den folgenden Code hinzu:

class NegativeNumberError(Exception):
    """Custom exception raised for negative numbers."""
    pass

def process_positive_number(number):
    if number < 0:
        raise NegativeNumberError("Negative numbers are not allowed")
    print(f"Processing positive number: {number}")

try:
    process_positive_number(-10)
except NegativeNumberError as e:
    print(f"Caught custom exception: {e}")

try:
    process_positive_number(20)
except NegativeNumberError as e:
    print(f"Caught custom exception: {e}")

Speichern Sie die Datei und führen Sie sie im Terminal aus:

python ~/project/custom_exception.py

Die Ausgabe wird sein:

Caught custom exception: Negative numbers are not allowed
Processing positive number: 20

In diesem Beispiel haben wir unsere eigene NegativeNumberError definiert und sie unter einer bestimmten Bedingung ausgelöst. Der try...except-Block fängt dann spezifisch diesen benutzerdefinierten Fehlertyp ab, wodurch die Fehlerbehandlung präziser wird.

Zusammenfassung

In diesem Lab haben Sie gelernt, wie man eine robuste Fehlerbehandlung (Error Handling) in Python implementiert. Sie begannen mit der Verwendung eines try...except-Blocks, um einen spezifischen ValueError von Benutzereingaben abzufangen. Anschließend erweiterten Sie dies, indem Sie mehrere Ausnahmetypen behandelten, sowohl separat als auch in einem einzigen Block. Sie lernten auch, die else-Klausel zu verwenden, um Code nur dann auszuführen, wenn keine Ausnahmen auftreten, und die finally-Klausel, um Aufräumarbeiten (Cleanup code) in allen Situationen auszuführen. Schließlich übten Sie das Erstellen und Auslösen benutzerdefinierter Ausnahmen (Custom Exceptions), um anwendungsspezifische Fehler zu behandeln, wodurch Ihr Code lesbarer und wartbarer wurde.