Python Debugging
Finden und Beheben von Fehlern
Beim Programmieren und in der Softwareentwicklung ist Debugging der Prozess des Findens und Behebens von Bugs (Fehlern oder Problemen, die eine korrekte Funktion verhindern) in Computerprogrammen, Software oder Systemen.
Auslösen von Ausnahmen (Raising Exceptions)
Ausnahmen werden mit einer raise-Anweisung ausgelöst. Im Code besteht eine raise-Anweisung aus Folgendem:
- Das Schlüsselwort
raise - Ein Aufruf der Funktion
Exception() - Ein String mit einer hilfreichen Fehlermeldung, der an die Funktion
Exception()übergeben wird
# raise statement: manuelles Auslösen einer Ausnahme mit einer benutzerdefinierten Nachricht
raise Exception('This is the error message.')
Traceback (most recent call last):
File "<pyshell#191>", line 1, in <module>
raise Exception('This is the error message.')
Exception: This is the error message.
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
throwraiseerrorexceptionTypischerweise ist es der Code, der die Funktion aufruft, und nicht die Funktion selbst, der weiß, wie eine Ausnahme zu behandeln ist. Daher werden Sie häufig eine raise-Anweisung innerhalb einer Funktion und die Anweisungen try und except im aufrufenden Code sehen.
# Raise exceptions in function, handle them in calling code
def box_print(symbol, width, height):
if len(symbol) != 1:
raise Exception('Symbol must be a single character string.')
if width <= 2:
raise Exception('Width must be greater than 2.')
if height <= 2:
raise Exception('Height must be greater than 2.')
print(symbol * width)
for i in range(height - 2):
print(symbol + (' ' * (width - 2)) + symbol)
print(symbol * width)
# Handle exceptions when calling the function
for sym, w, h in (('*', 4, 4), ('O', 20, 5), ('x', 1, 3), ('ZZ', 3, 3)):
try:
box_print(sym, w, h)
except Exception as err: # Catch exception and print error message
print('An exception happened: ' + str(err))
****
* *
* *
****
OOOOOOOOOOOOOOOOOOOO
O O
O O
O O
OOOOOOOOOOOOOOOOOOOO
An exception happened: Width must be greater than 2.
An exception happened: Symbol must be a single character string.
Lesen Sie mehr über Exception Handling.
Den Traceback als String erhalten
Der traceback wird von Python angezeigt, wenn eine ausgelöste Ausnahme unbehandelt bleibt. Sie können ihn aber auch als String erhalten, indem Sie traceback.format_exc() aufrufen. Diese Funktion ist nützlich, wenn Sie die Informationen aus dem Traceback einer Ausnahme benötigen, aber trotzdem eine except-Anweisung verwenden möchten, um die Ausnahme elegant zu behandeln. Sie müssen das traceback-Modul von Python importieren, bevor Sie diese Funktion aufrufen.
# traceback.format_exc(): Traceback als String für Logging/Debugging erhalten
import traceback
try:
raise Exception('This is the error message.')
except:
with open('errorInfo.txt', 'w') as error_file:
error_file.write(traceback.format_exc()) # Traceback in Datei schreiben
print('The traceback info was written to errorInfo.txt.')
116
The traceback info was written to errorInfo.txt.
Die 116 ist der Rückgabewert der write()-Methode, da 116 Zeichen in die Datei geschrieben wurden. Der traceback-Text wurde in errorInfo.txt geschrieben.
Traceback (most recent call last):
File "<pyshell#28>", line 2, in <module>
Exception: This is the error message.
Assertions (Zusicherungen)
Eine Assertion ist eine Plausibilitätsprüfung, um sicherzustellen, dass Ihr Code nichts offensichtlich Falsches tut. Diese Plausibilitätsprüfungen werden durch assert-Anweisungen durchgeführt. Wenn die Plausibilitätsprüfung fehlschlägt, wird eine Ausnahme vom Typ AssertionError ausgelöst. Im Code besteht eine assert-Anweisung aus Folgendem:
- Das Schlüsselwort
assert - Eine Bedingung (d. h. ein Ausdruck, der zu
TrueoderFalseausgewertet wird) - Ein Komma
- Ein
string, der angezeigt wird, wenn die BedingungFalseist
# assert statement: Bedingung prüfen, AssertionError auslösen, wenn False
pod_bay_door_status = 'open'
assert pod_bay_door_status == 'open', 'The pod bay doors need to be "open".' # Erfolgreich
pod_bay_door_status = 'I\'m sorry, Dave. I\'m afraid I can\'t do that.'
assert pod_bay_door_status == 'open', 'The pod bay doors need to be "open".' # Löst AssertionError aus
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
assert pod_bay_door_status == 'open', 'The pod bay doors need to be "open".'
AssertionError: The pod bay doors need to be "open".
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
assert-Anweisung fehlschlägt?AssertionError wird ausgelöst und das Programm sollte abstürzenVereinfacht ausgedrückt besagt eine Assert-Anweisung: „Ich versichere, dass diese Bedingung wahr ist, und wenn nicht, liegt irgendwo im Programm ein Fehler vor.“ Im Gegensatz zu Ausnahmen sollte Ihr Code Assert-Anweisungen nicht mit try und except behandeln; wenn ein Assert fehlschlägt, sollte Ihr Programm abstürzen. Durch dieses schnelle Scheitern verkürzen Sie die Zeit zwischen der ursprünglichen Ursache des Fehlers und dem ersten Auftreten des Fehlers. Dies reduziert die Menge an Code, die Sie überprüfen müssen, bevor Sie den fehlerverursachenden Code finden.
Deaktivieren von Assertions
Assertions können deaktiviert werden, indem die Option -O beim Ausführen von Python übergeben wird.
Logging (Protokollierung)
Um das logging-Modul so zu aktivieren, dass Log-Meldungen während der Programmausführung auf Ihrem Bildschirm angezeigt werden, kopieren Sie Folgendes an den Anfang Ihres Programms:
import logging
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s- %(message)s')
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
logging-Moduls in Python?Angenommen, Sie haben eine Funktion zur Berechnung der Fakultät einer Zahl geschrieben. In der Mathematik ist die Fakultät von 4 gleich 1 × 2 × 3 × 4, also 24. Die Fakultät von 7 ist 1 × 2 × 3 × 4 × 5 × 6 × 7, also 5.040. Öffnen Sie ein neues Dateieditorfenster und geben Sie den folgenden Code ein. Er enthält einen Fehler, aber Sie werden auch mehrere Log-Meldungen einfügen, um sich bei der Fehlersuche zu helfen. Speichern Sie das Programm als factorialLog.py.
import logging
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s- %(message)s')
logging.debug('Start of program')
def factorial(n):
logging.debug('Start of factorial(%s)' % (n))
total = 1
for i in range(0, n + 1):
total *= i
logging.debug('i is ' + str(i) + ', total is ' + str(total))
logging.debug('End of factorial(%s)' % (n))
return total
print(factorial(5))
logging.debug('End of program')
2015-05-23 16:20:12,664 - DEBUG - Start of program
2015-05-23 16:20:12,664 - DEBUG - Start of factorial(5)
2015-05-23 16:20:12,665 - DEBUG - i is 0, total is 0
2015-05-23 16:20:12,668 - DEBUG - i is 1, total is 0
2015-05-23 16:20:12,670 - DEBUG - i is 2, total is 0
2015-05-23 16:20:12,673 - DEBUG - i is 3, total is 0
2015-05-23 16:20:12,675 - DEBUG - i is 4, total is 0
2015-05-23 16:20:12,678 - DEBUG - i is 5, total is 0
2015-05-23 16:20:12,680 - DEBUG - End of factorial(5)
0
2015-05-23 16:20:12,684 - DEBUG - End of program
Logging Levels (Protokollierungsebenen)
Logging-Level bieten eine Möglichkeit, Ihre Log-Meldungen nach Wichtigkeit zu kategorisieren. Es gibt fünf Logging-Level, die in Tabelle 10-1 von der geringsten zur höchsten Wichtigkeit beschrieben werden. Meldungen können auf jeder Ebene mit einer anderen Logging-Funktion protokolliert werden.
| Level | Logging Function | Description |
|---|---|---|
DEBUG | logging.debug() | Die niedrigste Stufe. Wird für kleine Details verwendet. Normalerweise interessieren Sie sich nur für diese Meldungen bei der Diagnose von Problemen. |
INFO | logging.info() | Wird verwendet, um Informationen über allgemeine Ereignisse in Ihrem Programm aufzuzeichnen oder zu bestätigen, dass Dinge an ihrer Stelle im Programm funktionieren. |
WARNING | logging.warning() | Wird verwendet, um auf ein potenzielles Problem hinzuweisen, das die Funktion des Programms nicht verhindert, aber in Zukunft tun könnte. |
ERROR | logging.error() | Wird verwendet, um einen Fehler aufzuzeichnen, der dazu führte, dass das Programm etwas nicht tun konnte. |
CRITICAL | logging.critical() | Die höchste Stufe. Wird verwendet, um einen fatalen Fehler anzuzeigen, der dazu geführt hat oder kurz davor steht, dass das Programm vollständig beendet wird. |
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
INFOWARNINGERRORDEBUGDeaktivieren des Loggings
Nachdem Sie Ihr Programm debuggt haben, möchten Sie wahrscheinlich nicht, dass all diese Log-Meldungen den Bildschirm überfluten. Die Funktion logging.disable() deaktiviert diese, sodass Sie nicht manuell alle Logging-Aufrufe aus Ihrem Programm entfernen müssen.
import logging
logging.basicConfig(level=logging.INFO, format=' %(asctime)s -%(levelname)s - %(message)s')
logging.critical('Critical error! Critical error!')
2015-05-22 11:10:48,054 - CRITICAL - Critical error! Critical error!
logging.disable(logging.CRITICAL)
logging.critical('Critical error! Critical error!')
logging.error('Error! Error!')
Logging in eine Datei
Anstatt die Log-Meldungen auf dem Bildschirm anzuzeigen, können Sie sie in eine Textdatei schreiben. Die Funktion logging.basicConfig() akzeptiert ein Schlüsselwortargument filename, wie folgt:
import logging
logging.basicConfig(filename='myProgramLog.txt', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
logging.file()filename an logging.basicConfig()logging.write()