Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Gartenautomation
  • Arduino
  • ESP32 & Co.
  • Raspberry Pi & Pico
  • Solo Mining
  • Deutsch
  • English
Menu

Python #21 – Exceptionhandling

Posted on 23. Juli 202030. April 2023 by Stefan Draeger

In diesem Beitrag möchte ich dir zeigen wie du dein Programm robust schreiben kannst und auf eventuell auftretenne Fehler reagieren kannst. Die Fehlerbehandlung in Pythonskripten habe ich bereits im Beitrag Python #8: Fehlerbehandlung behandelt, jedoch nicht ausführlich genug und daher hier nun deutlich ausführlicher!

  • Was ist ein Fehler?
  • Wie sollte auf einen Fehler reagiert werden?
  • ein einfaches Beispiel
    • Abfangen der Exception „division by zero“
  • Abfangen von mehreren Exceptions
  • Benutzereingaben validieren
  • eigene Exceptions erstellen

Was ist ein Fehler?

Ein Fehler oder auch Bug genannt ist ein Fehlverhalten einer Anwendung. Dabei muss man unterscheiden zwischen Programmierfehler (nicht oder nur teilweise umgesetzte Story) und Eingabefehler durch den Benutzer. Wobei letzteres auch wieder nicht korrekt durch den Programmierer abgefangen wurde (ggf. eine gap in der Anforderung).

Wie sollte auf einen Fehler reagiert werden?

Wie man auf einen Fehler reagiert ist immer abhängig ob andere Prozesse von dem Ergebnis abhängig sind und ob die Anwendung auch mit diesem Ereignis für den Benutzer weitergeführt werden kann. Kurzum wenn ein Fehler auftritt sollte eine Entsprechende Meldung an den Benutzer erfolgen das ein Fehler aufgetreten ist.

Wenn es ein schwerwiegender Fehler ist sollte das Programm an der Stelle beendet werden! Im Idealfall wird die Anwendung beim erneuten starten an der Stelle fortfahren. Dieses kann zbsp. gemacht werden wenn das Programm eine Datei benötigt welche beim ersten Durchlauf nicht zur Verfügung stand.

ein einfaches Beispiel

Hier nun ein kleines Beispiel wie ein Fehler auftreten kann.

zahl1 = 5
zahl2 = 0
ergebnis = zahl1 / zahl2
print(ergebnis)

Was passiert wenn man 5 durch 0 teilt? Richtig! Ein Fehler, denn Teilen durch 0 ist nicht möglich.

Im nachfolgenden Stacktrace wird aufgezeigt welcher Fehler aufgetreten ist, sowie an welcher Stelle im Quellcode.

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-2-f73501945a8c> in <module>()
      1 zahl1 = 5
      2 zahl2 = 0
----> 3 ergebnis = zahl1 / zahl2
      4 print(ergebnis)

ZeroDivisionError: division by zero

Für den technisch nicht versierten Benutzer der Anwendung ist dieser Fehler nicht sehr hilfreich. Man sollte also nun diesen Fehler abfangen und eine „vernünftige“ Fehlermeldung ausgeben.

Abfangen der Exception „division by zero“

Wollen wir zunächst die Exception abfangen, dazu packen wir unser Programm in ein Try-Except Block. Der Block beginnt mit einem „try:“, in diesen Bereich kommt der Code welcher ggf. einen Fehlerfall erzeugen kann. Im Bereich „except“ definieren wir die ggf. auftretene Exception. In unserem Fall ist es der „ZeroDivisionError“, zusätzlich kann man diese Exception auf in eine Variable legen um dann auf Wert wie die Message, Argumente usw. zugreifen zu können.

try:
    zahl1 = 5
    zahl2 = 0
    ergebnis = zahl1 / zahl2
    print(ergebnis)
except ZeroDivisionError as error:
    print("Error:", error)

Wenn wir nun den Code ausführen wir der Fehler abgefangen und eine etwas bessere Meldung ausgegeben:

Error: division by zero

Jedoch haben wir nur diese eine Exception abgehandelt es kann nun natürlich auch eine andere Exception auftreten welche dann wieder abgefangen werden muss.

Abfangen von mehreren Exceptions

Im ersten Beispiel haben wir eine Exception vom Typ „ZeroDivisionError“ ausgelöst. Wenn man nun mehr als eine Exception erwartet so kann man diese mit einer Klammer und Kommaseparariert aufführen.

try:
    zahl1 = 5
    zahl2 = 1
    ergebnis = zahl1 / zahl2
    raise NameError('Hallo Welt!')
    print(ergebnis)
except (ZeroDivisionError, NameError) as error:
    print("Error:", error)

Mit dem Befehl „raise“ können wir eine Exception werfen, dieses kann man zbsp. machen wenn eine Bedingung nicht erfüllt ist und die Ausführung abgebrochen werden soll.

Benutzereingaben validieren

Nehmen wir nun unser kleines Programm und erweitern dieses um die Fähigkeit das der Benutzer die Zahl selber eingeben kann, ABER wir wollen nur Zahlen kleiner gleich 5 verarbeiten. Dieses prüfen wir mit einer Bedingten Anweisung. Wenn die eingegebene Zahl kleiner gleich 5 ist werfen wir eine Exception und berechen das Programm ab.

try:
    zahl1 = int(input("Eine Zahl <= 5 "))
    zahl2 = 1
    ergebnis = zahl1 / zahl2
    print(ergebnis)
    if(ergebnis > 5):
        raise NameError('Zahl ist größer als 5')
except (ZeroDivisionError, NameError) as error:
    print("Error:", error)

Wenn der Code ausgeführt wird, kann man nun nun eine Eingabe tätigen. Wie bereits erwähnt erwarten wir eine Zahl kleiner gleich 5.

Wenn jetzt aber der Benutzer einen Buchstaben eingibt erhält man eine andere Exception welche wir bisher nicht behandelt haben.

Python3 - Exceptionhandling, ValueError beim umwandeln von String nach Integer
Python3 – Exceptionhandling, ValueError beim umwandeln von String nach Integer

In der Zeile 2 nehmen wir die Eingabe auf der Konsole entgegen und wandeln diese ohne weitere Prüfung in eine Zahl um hier müßte also zusätzlich geprüft werden ob der Benutzer eine Zahl eingegeben hat. Oder wir reagieren auf einen ValueError.

try:
    zahl1 = int(input("Eine Zahl <= 5 "))
    zahl2 = 1
    ergebnis = zahl1 / zahl2
    print(ergebnis)
    if(ergebnis > 5):
        raise NameError('Zahl ist größer als 5')
except (ZeroDivisionError, NameError) as error:
    print("Error:", error)
except ValueError as valueError:
    print("Fehler bei der Eingabe!")

Wir haben nun einen zusätzlichen Zweig für den ValueError hinzugefügt. Wenn also ein ValueError auftritt wird der Text Fehler bei der Eingabe!“ ausgegeben. Zusätzlich sollten wir jedoch den eingegebenen Text validieren und somit den Quellcode deutlich robuster gestalten.

try:
    eingabe = input("Eine Zahl <= 5 ")
    if not eingabe.isdigit():
        raise ValueError("Die Eingabe ist keine Zahl!")
    zahl1 = int(eingabe)
    zahl2 = 1
    ergebnis = zahl1 / zahl2
    print(ergebnis)
    if(ergebnis > 5):
        raise NameError('Zahl ist größer als 5')
except (ZeroDivisionError, NameError) as error:
    print("Error:", error)
except ValueError as valueError:
    print(valueError)
Eine Zahl <= 5 g
Die Eingabe ist keine Zahl!

eigene Exceptions erstellen

In den zuvor gezeigten Quellcodes haben wir die ValueError, NameError und ZeroDivisionError verwendet. Es gibt aber auch fälle da gibt es keine passende Exception zbsp. wenn ein Wert nicht wie erwartet ist. Im nachfolgenden soll der Benutzer eine Zahl zwischen 0 und 100 eingeben also alles unter 0  und größer als 100 sind nicht valide Werte und das Programm soll vorzeitig beendet werden.

Zunächst erstellen wir und unsere eigene Exception, ich wähle hier den Namen „OutOfBoundException“ denn der Zahlenwert ist ja nicht zwischen den beiden gewählten bereichen.

class OutOfBoundsException(Exception):
    
    def __init__(self, message):
        self.message = message

Nach der Validierung ob die Eingabe eine Zahl ist, wird also nun geprüft ob der Wert zwischen 0 und 100 liegt wenn dieses nicht so ist wird unsere CustomException gworfen.

if zahl < 0  or zahl > 100:
       raise(OutOfBoundsException("Fehler! Die Zahl muss zwischen 0 und 100 liegen!"))

Hier nun das kleine Programm zum prüfen einer Eingabe auf Zahl und der Wert zwischen 0 und 100.

class OutOfBoundsException(Exception):
    
    def __init__(self, message):
        self.message = message
                
try:
    eingabe = input("Eine Zahl >= 0 & <= 100 ")
    if not eingabe.isdigit():
        raise ValueError("Die Eingabe ist keine Zahl!")
    zahl = int(eingabe)
    if zahl < 0  or zahl > 100:
        raise(OutOfBoundsException("Fehler! Die Zahl muss zwischen 0 und 100 liegen!"))
except ValueError as valueError:
    print(valueError)
except OutOfBoundsException as oObException:
    print(oObException

Schreibe einen Kommentar Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen

Tel.: 01778501273
E-Mail: info@draeger-it.blog

Folge mir auf

  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2025 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Verwalten von {vendor_count}-Lieferanten Lese mehr über diese Zwecke
Einstellungen anzeigen
{title} {title} {title}