Handle error types and troubleshoot (debug). For interactive reading and executing code blocks and find b02-pyerror.ipynb, or install Python and JupyterLab locally.
Watch this section as a video
Watch this section as a video on the @Hydro-Morphodynamics channel on YouTube.
Fehler und Ausnahmen¶
Fehlertypen¶
Um err ist menschlich und Python hilft uns, unsere Fehler zu finden, indem wir errorTyp Beschreibungen. Hier eine Liste von gemeinsamen Fehlern, die beim Schreiben/Laufen von Python-Code auftreten können:
| Error Type | Description | Example |
|---|---|---|
KeyError | A mapping key is not found. | May occur when referencing a non-existing dictionary key. |
ImportError | Importing a module that does not exist | import the-almighty-module |
IndentationError | The code block indentation is not correct. | See code style descriptions |
IndexError | An index outside the range of a variable is used. | nums = [1, 2]; print(nums[2]) |
NameError | An undefined variable is referenced. | print(a) |
TypeError | Incompatible data types and/or operators are used together. | "my_string" / 10 |
ValueError | Right data type, but an inappropriate value. | int(input("Number:")) answered with t |
ZeroDivisionError | Division by zero. | 3 / 0 |
Dennoch gibt es viele weitere Fehlertypen, die auftreten können, und Python-Entwickler pflegen umfassende Beschreibungen von integrierten Ausnahmen auf der Python
Ausnahme Handling mit try - except¶
try und except Keywords testen einen Code-Block und wenn er abstürzt, wird eine exception angehoben, aber das Skript selbst wird nicht abstürzen (sofern nicht anders in der except-Anweisung definiert). Die Grundstruktur ist:
try:
# code block
except ErrorType:
print("Error / warning message.")Die ErrorType ist technisch nicht notwendig (d.h. auch except: macht den Job), aber das Hinzufügen einer ErrorType ist eine gute Praxis, um eine effiziente Debugging zu ermöglichen oder andere Benutzer den Ursprung eines Fehlers oder einer Warnung zu verstehen. Im folgenden Beispiel wird die Implementierung eines ValueError in einem interaktiven Konsolenskript dargestellt, das es den Benutzern erfordert, einen ganzzahligen Wert einzugeben.
try:
x = int(input("How many scoops of ice cream do you want? "))
except ValueError:
print("What's that? sorry, please try again.")How many scoops of ice cream do you want? 4
Die try-Anweisung kann auch eine else-Klausel haben, die nur dann läuft, wenn der try-Block keine Ausnahme erhoben hat (hier unter Verwendung von Helper-Funktionen wie key_not_found oder handle_value):
try:
value = a_dictionary[key]
except KeyError:
return key_not_found(key)
else:
return handle_value(value)pass Statement¶
Wenn wir anfangen, Code zu schreiben, stehen wir oft vor einer komplexen Herausforderung, die nicht alle zu einer Zeit kodiert werden kann. Für diese Herausforderungen hilft uns Python mit der pass-Anweisung, die die Implementierung von leeren (void)-Codeblöcken und laufendem Code inkremental ermöglicht (d.h. den Code zu debuggen). Darüber hinaus helfen die obigen Fehlertypdefinitionen, Fehler zu verstehen, die wir in bereits geschriebenem Code gemacht haben. Um später zu definieren, was passiert, wenn Python in eine NameError läuft, kann eine pass-Anweisung wie folgt umgesetzt werden:
try:
a = 5
c = a + b # we want to define b later on with a complex formula
except NameError:
pass # we know that we did not define b yetProtokoll¶
Die print()-Funktion ist nützlich, um Variablen oder Berechnungsfortschritte an die Konsole zu drucken (nicht zu oft; Druck nimmt Zeit und verlangsamt Berechnungen). Für eine robuste Meldung von Fehlern oder anderen wichtigen Meldungen stellt eine Log-Datei jedoch eine bessere Wahl dar. Was ist also eine Log-Datei oder der Akt des Protokollierens? Wir kennen Logbücher von Entdeckern oder Abenteurern, die ihre Erfahrungen nach Terminen aufschreiben. Ebenso kann ein Code aufschreiben (log) seine “Erfahrungen”, aber in einer Datei anstelle eines Buches. Zu diesem Zweck hat Python den Standard Logging library. Für den Moment genügt es zu wissen, dass die logging-Bibliothek in jedem Python-Skript mit import logging importiert werden kann (weitere Informationen zu Paketen, Modulen und Bibliotheken finden Sie im Abschnitt Pakete, Module und Bibliotheken).
Der folgende Codeblock importiert das logging-Modul und verwendet die folgenden Keyword-Argumente, um die logging.basicConfig:
filename="my-logfile.log"schreibt das Logging-Modul Nachrichten an eine Datei namens"my-logfile.log"im selben Verzeichnis, in dem das Python-Skript läuft.format="%(asctime)s - %(message)ssetzt das Logging-Format aufYYYY-MM-DD HH:MM:SS.sss -Nachrichtentext (weitere Formatoptionen sind in der Python docs] aufgeführt.filemode="w"überschreibt frühere Meldungen in der Log-Datei (entfernt dieses Argument, um Nachrichten anstelle von Überschreiben anzuhängen).level=logging.DEBUGdefiniert die Schwere der in die Log-Datei geschriebenen Nachrichten, wobeiDEBUGfür Problemdiagnosen in Codes ausreichend ist; andere Ebenen der Eventschwere sind:logging.INFO, um alle Bestätigungsmeldungen von Ereignissen zu schreiben, die wie erwartet funktionierten.logging.WARNING(default), um anzuzeigen, wann ein unerwartetes Ereignis passiert ist oder wann ein Ereignis in Zukunft einen Fehler verursachen kann (z.B. wegen unzureichender Festplattenfläche).logging.ERROR, um ernsthafte Probleme zu melden, die den Code abstürzen oder nicht das gewünschte Ergebnis erzeugen.logging.CRITICAList ein breiterer schwerer Problemindikator, bei dem das Programm selbst möglicherweise nicht weiterlaufen kann (z.B. nicht nur der Code, sondern auch Python abstürzt).
Bis hier werden Nachrichten nur in die Log-Datei geschrieben, aber wir können keine Nachricht in der Konsole sehen. Um eine gleichzeitige Anmeldung zu einer Logdatei und der Konsole (Python terminal) zu ermöglichen, verwenden Sie logging.getLogger().addHandler(logging.StreamHandler()), die einen io Stream-Handler anschließt.
Um eine Nachricht an die Protokolldatei (und Python Terminal) zu schreiben, verwenden Sie
logging.debug("message")für Codediagnosen,logging.info("message")für Fortschrittsinformationen (wie wir zuvorprint("message")verwendet haben),logging.warning("warning-message")für unerwartete Eventdokumentation (ohne Programm unterbrochen),logging.error("error-message")für Fehler, die eine Störung des Codes verursachen, undlogging.critical("message")für kritische Fehler, die zu Programm (Python) Crashs führen können.
Warning, error und kritische-Nachrichten sollten in Ausnahme-Anhebungen umgesetzt werden (siehe oben try -except-Anweisungen).
Am Ende eines Skripts sollte die Protokollierung mit logging.shutdown() gestoppt werden, da sonst die Protokolldatei von Python gesperrt wird und der Python Kernel angehalten werden muss, um Änderungen (z.B. Entfernen) in die Protokolldatei zu erstellen.
import logging
logging.basicConfig(filename="my-logfile.log", format="%(asctime)s - %(message)s", filemode="w", level=logging.DEBUG)
logging.getLogger().addHandler(logging.StreamHandler())
logging.debug("This message is logged to the file.")
logging.info("Less severe information is also logged to the file.")
logging.warning("Warning messages are logged, too.")
a = "text"
try:
logging.info(str(a**2))
except TypeError:
logging.error("The variable is not numeric.")
# stop logging
logging.shutdown()This message is logged to the file.
Less severe information is also logged to the file.
Warning messages are logged, too.
The variable is not numeric.
Und so sieht my-logfile.log aus:
2025-05-25 18:51:46,657 - This message is logged to the file.
2025-05-25 18:51:46,666 - Less severe information is also logged to the file.
2025-05-25 18:51:46,667 - Warning messages are logged, too.
2025-05-25 18:51:46,669 - The variable is not numeric.Veranstaltungen können auch dokumentiert werden, indem ein Loggerobjekt mit logger = logging.getLogger(__name__). Diese günstige Lösung wird für fortgeschrittene Codierungen empfohlen, z.B. ein neues (custom) Python library (weiterlesen in den Python docs on advanced logging). Ein Beispielskript mit einem ausgefeilteren Logger wird mit dem Logger-Skript unter dem Kurs repository.
Debugging¶
Sobald Sie mehr oder weniger komplexen Code geschrieben haben, ist die ultimative Frage: Will es laufen? Die enttäuschende Antwort ist nicht (in den meisten Fällen), aber es gibt ein Mittel namens debugging, das ist der Akt der Beseitigung von Fehlern (Fehler) aus dem Code. Dennoch können große Code-Blöcke ein Albtraum für Debugging sein, und dieser Abschnitt bietet einige Prinzipien, um den Faktor der Scharfheit zu reduzieren, die Debugging kann beinhalten.
Verwendung von Ausnahmen¶
Kritische Code-Blöcke genau mit try - except Keywords und möglichen Fehlern. Dies wird später dazu beitragen, mögliche Fehlerursachen zu identifizieren.
Deskriptive Variablennamen verwenden¶
Geben Sie Variablen, Funktionen und andere Objekte beschreibende und aussagekräftige Namen. Abkürzungen werden immer notwendig sein, aber diese sollten beschreibend sein (z.B. Akronyme verwenden). Für Variablen und Funktionen verwenden Sie nur kleine Buchstaben. Für Klassen verwenden CamelCase.
Umgang mit Fehlern¶
Wird eine Fehlermeldung angehoben, lesen Sie die Fehlermeldung gründlich und mehrmals auf ** verstehen Sie den Ursprung* des Fehlers. Fehlermeldungen geben häufig das jeweilige Skript und die Zeilennummer an, in der der Fehler angehoben wurde. Falls der Fehler kein offensichtliches Ergebnis von fehlerhaften Datentypen oder einer der oben genannten Fehlermeldungen ist (z.B. ein Fehler, der innerhalb eines externen Moduls/Pakets angehoben wird), verwenden Sie Ihre Lieblings-Suchmaschine, um den Fehler zu beheben.
Ausgabe verifizieren¶
Die Tatsache, dass Code läuft, bedeutet nicht inhärent, dass das Ergebnis (Output) die gewünschte Ausgabe ist. Führen Sie daher den Code mit Eingabeparametern aus, die die vorhandene Ausgabe von einer anderen Quelle (z.B. manuelle Berechnung) liefern und überprüfen, ob die codeproduzierte Ausgabe dem vorhandenen (benötigten) Ausgang entspricht.
Code mit einem strukturierten Ansatz¶
Denken Sie an die Codestruktur, bevor Sie mit einem Bündel von Code-Blöcken beginnen und sie in einigen Python-Dateien speichern. Struktur- und/oder Verhaltensdiagramme helfen bei der Entwicklung eines ausgeklügelten Coderahmens. Die Entwickler der Unified Modeling Language (UML) bieten solide Leitlinien für die Entwicklung von Struktur und Verhalten UML charts in der Softwaretechnik.
Weiche Alternativen¶
Erklären Sie Ihr Problem einem Freund oder sprechen Sie es einfach laut: Wiederholen und versuchen, ein Problem einer anderen Person zu erklären (auch wenn es nur eine imaginäre Person oder Gruppe von Menschen ist) stellt oft einen Ärger selbst dar.
Gehen Sie spazieren, schlafen Sie auf das Problem oder tun Sie andere Dinge mit niedriger Gehirnbesetzung. Während Sie sich mit anderen Dingen beschäftigen, denkt Ihr Gehirn weiterhin an das Problem (Wikipedia widmete sogar eine Seite zu diesem sogenannten Prozess von incubation).
