Effektives Debugging mit der Python Assert-Anweisung

Bist du ein Programmierer? Wenn dies der Fall ist, ist das Debuggen eine wesentliche Fähigkeit, unabhängig von der Sprache, in der Sie codieren. In diesem Artikel erfahren Sie, wie Sie die assert-Anweisung in Python für ein effektives Debugging verwenden.

Wenn Sie an einem Projekt arbeiten, definieren Sie mehrere Module. Dazu gehören Funktionen, Klassendefinitionen und mehr. Und Sie werden wahrscheinlich aufgrund eines Fehlers in der Implementierung auf Fehler oder unerwartete Ergebnisse stoßen. Assert-Anweisungen sind beim Debuggen eines solchen Codes hilfreich.

In diesem Tutorial lernen wir die Syntax zur Verwendung der assert-Anweisung kennen, gefolgt von Codebeispielen, um sie in Aktion zu sehen. Wir werden auch sehen, was Behauptungsfehler sind und wie wir sie verwenden können, um die Fehler im Code während der Entwicklung zu beheben.

Lass uns anfangen!

So verwenden Sie die Assert-Anweisung in Python

Wir werden die Syntax lernen, um die assert-Anweisung zu verwenden, und dann mit dem Codieren einiger Beispiele fortfahren.

Syntax der Assert-Anweisung

Beginnen wir mit der Syntax, um die assert-Anweisung in Python zu verwenden:

assert expression, message

Hier,

  • expression ist ein beliebiger gültiger Python-Ausdruck, der ausgewertet werden soll. Dies kann eine Bedingung für den Wert einer Variablen, den Wahrheitswert einer Variablen, den Rückgabewert einer Funktion und mehr sein.
  • Solange der Ausdruck True ergibt, gibt die Assert-Anweisung keinen Fehler aus und gibt nichts zurück. Dies zeigt an, dass das Programm wie erwartet funktioniert.
  • Wenn der Ausdruck nicht mehr True ist, wird eine AssertionError-Ausnahme ausgelöst.
  • Nachricht ist eine optionale Zeichenfolge. Sie können eine Meldung angeben, die in der Rückverfolgung angezeigt wird, wenn eine AssertionError-Ausnahme ausgelöst wird.

Lassen Sie uns als Nächstes einige Beispiele programmieren, bei denen uns die assert-Anweisung dabei helfen kann, saubereren und fehlerfreien Code zu schreiben.

Die in diesem Tutorial verwendeten Codebeispiele finden Sie in diesem GitHub-Gist.

Beispiele für die Assert-Anweisung von Python

Betrachten Sie das folgende Beispiel. Angenommen, Sie haben eine Rabattvariable in Ihrem Code. Aber Sie möchten, dass sein Wert immer kleiner oder gleich max_discount ist.

  So installieren Sie Docker Engine auf CentOS

Um zu überprüfen, ob Sie die Rabattvariable nicht versehentlich auf einen Wert gesetzt haben, können Sie eine Assertion hinzufügen. Der auszuwertende Ausdruck lautet: discount <= max_discount.

>>> max_discount = 50
>>> discount = 20
>>> assert discount <= max_discount

Hier ist discount (20) kleiner als max_discount (50). Die Assert-Anweisung wirft also keinen Fehler aus.

Die AssertionError-Ausnahme

Wenn die Rabattvariable auf einen Wert größer als max_discount festgelegt wird, wird eine AssertionError-Ausnahme ausgelöst.

>>> discount = 75
>>> assert discount <= max_discount
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

Wir wissen, dass wir mit der assert-Anweisung auch eine optionale Nachrichtenzeichenfolge angeben können.

Lassen Sie uns auch eine Nachrichtenzeichenfolge verwenden, die eine aussagekräftigere Diagnoseinformation liefert. Fügen wir der Assertion-Anweisung einen Python-F-String hinzu, der auch die Werte von discount und max_discount enthält.

>>> assert discount <= max_discount, f"discount should be at most {max_discount}; got discount = {discount}"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: discount should be at most 50; got discount = 75

Wie in der obigen Ausgabezelle zu sehen, enthält die Ausnahme AssertionError jetzt die Werte der Variablen discount und max_discount.

Debuggen und Testen von Python-Funktionen mit Assert

Beim Definieren von Funktionen können Sie manchmal versehentlich Bugs (logische Fehler) einführen, die verhindern, dass Ihre Funktion wie beabsichtigt funktioniert.

Nehmen wir ein Beispiel. Angenommen, es gibt einen Test in einer Klasse und die Schüler haben die Möglichkeit, eine Bonusfrage zu beantworten. Jeder Student, der die Bonusfrage versucht, erhält 10 zusätzliche Punkte im Test. 😄

Betrachten Sie die folgende Funktion get_final_score:

  • Es nimmt eine aktuelle Punktzahl, Punktzahl und einen booleschen Bonus auf.
  • Wenn ein Schüler die Bonusfrage beantwortet hat, ist der boolesche Bonus wahr und er erhält 10 Punkte mehr als seine aktuelle Punktzahl.
  • Die Funktion gibt dann die endgültige Punktzahl zurück.
def get_final_score(score,bonus):
    if bonus:
        score += 10
    return score

Machen wir ein paar Aufrufe der Funktion. Wir sehen, dass bei Ergebnissen von 34 und 40 mit Bonus auf True und False die Endergebnisse 44 bzw. 40 sind.

print(get_final_score(34,True))
# 44
print(get_final_score(40,False))
# 40

Die maximale Punktzahl für den Test beträgt jedoch beispielsweise 50. Wenn ein Schüler also 49 Punkte erzielt und auch die Bonusfrage beantwortet hat, berechnet die Funktion get_final_score glücklicherweise die Endpunktzahl von 59.

print(get_final_score(49,True))
# 59

Technisch ist es möglich. Aber nehmen wir an, dass ein Student nicht mehr als die maximal mögliche Punktzahl für den Test erreichen kann. 🙂

  Wie „Unified Memory“ Apples M1 ARM Macs beschleunigt

Lassen Sie uns also eine max_score-Variable initialisieren. Und erfassen Sie die zurückgegebene Punktzahl von der Funktion in der final_score-Variable.

Anschließend fügen wir eine Assertion hinzu, die prüft, ob final_score kleiner als max_score ist.

def get_final_score(score,bonus):
    if bonus:
        score += 10
    return score

final_score = get_final_score(47,True)
max_score = 50

assert final_score <= max_score

Wir erhalten nun eine AssertionError-Ausnahme für den Funktionsaufruf get_final_score(47,True):

Traceback (most recent call last):
  File "main.py", line 17, in <module>
    assert final_score <= max_score
AssertionError

Jetzt fügen wir der Python-assert-Anweisung einen beschreibenden f-String hinzu:

assert final_score <= max_score,f"final_score should be at most {max_score}; got {final_score}"
Traceback (most recent call last):
  File "main.py", line 17, in <module>
    assert final_score <= max_score,f"final_score should be at most {max_score}; got {final_score}"
AssertionError: final_score should be at most 50; got 57

Ändern der Funktion

Lassen Sie uns zurückgehen und die Definition der Funktion get_final_score ändern, um das unerwartete Verhalten zu beheben:

  • Die Funktion get_final_score nimmt auch max_score als Parameter.
  • Wir prüfen, ob der Bonus wahr ist. Wenn True, addieren wir 10 Punkte zur Score-Variablen.
  • Dann prüfen wir, ob score größer als max_score ist. Wenn ja, geben wir max_score zurück.
  • Andernfalls geben wir die Punktzahl zurück.

Wir haben jetzt sichergestellt, dass die Endpunktzahl immer kleiner oder gleich max_score ist.

def get_final_score(score,bonus,max_score):
    if bonus:
        score += 10
    if score > max_score:
        return max_score
    return score

Schreiben Sie als schnelle Übung einige Behauptungen, um zu bestätigen, dass die Funktion jetzt wie erwartet funktioniert.

  So fügen Sie ein Spiel manuell zu GeForce Experience hinzu

Ein Hinweis zur AssertionError-Ausnahme

Obwohl eine AssertionError-Ausnahme auftritt, wenn der Ausdruck als False ausgewertet wird, sollten wir daran denken, solche Fehler nicht als Ausnahmen zu behandeln. Das heißt, wir sollten so etwas nicht tun:

try:
    <doing this>
except AssertionError:
    <do this>

Im vorherigen Beispiel zu get_final_score haben wir die Assertion verwendet, um zu prüfen, ob final_score kleiner als max_score ist. Dann haben wir die Funktionsdefinition so modifiziert, dass es keine Behauptungsfehler gibt.

Dafür sind Behauptungen da. Sie sind Plausibilitätsprüfungen für Code und helfen beim Schreiben von sauberem Code. Die Ausnahmebehandlung hingegen dient dazu, unerwartete Fehler zur Laufzeit zu antizipieren und zu behandeln. Diese enthalten häufig ungültige Eingabetypen und -werte.

Zusammenfassend sollten Sie die Python-Assert-Anweisung für ein effektives Debugging verwenden und AssertionErrors nicht als Ausnahmen behandeln.

Abschluss

Dieses Tutorial hat Ihnen geholfen zu verstehen, wie Sie die Assert-Anweisung in Python verwenden. Hier ist eine Zusammenfassung dessen, was Sie gelernt haben:

  • Python-Assert-Anweisungen (Assertionen) haben die Form Assertion-Ausdruck. Dies prüft, ob der Ausdruck wahr ist. Wenn es nicht zu True ausgewertet wird, wird eine AssertionError-Ausnahme ausgelöst.
  • Sie können das Assert auch mit der Syntax Assert-Ausdruck, Nachricht verwenden. Dadurch wird die Nachrichtenzeichenfolge immer dann ausgegeben, wenn eine AssertionError-Ausnahme auftritt.
  • Sie sollten daran denken, keine Ausnahmebehandlung zu implementieren, um Behauptungsfehler zu behandeln. Und verwenden Sie Zusicherungen als hilfreiches Debugging-Tool für Plausibilitätsprüfungen Ihres Codes.

Als Entwickler helfen Ihnen Behauptungen beim Debuggen. Um sicherzustellen, dass alle einzelnen Komponenten (Module) des Projekts wie erwartet funktionieren, können Sie lernen, wie man Unit-Tests in Python schreibt.

Sehen Sie sich als Nächstes diese Liste mit Python-Projekten für Anfänger an, an denen Sie arbeiten können.