Ich habe Quellcode gelesen und an mehreren Stellen die Verwendung von gesehen assert
.
Was bedeutet es genau? Was ist seine Verwendung?
python
assert
assertions
Hossein
quelle
quelle
Antworten:
Die
assert
Anweisung existiert in fast jeder Programmiersprache. Es hilft dabei, Probleme frühzeitig in Ihrem Programm zu erkennen, wenn die Ursache klar ist, und nicht später als Nebeneffekt einer anderen Operation.Wenn Sie das tun...
... Sie weisen das Programm an, diese Bedingung zu testen und sofort einen Fehler auszulösen, wenn die Bedingung falsch ist.
In Python entspricht dies in etwa:
Probieren Sie es in der Python-Shell aus:
Zusicherungen können eine optionale Nachricht enthalten, die Sie beim Ausführen des Interpreters deaktivieren können.
So drucken Sie eine Nachricht, wenn die Zusicherung fehlschlägt:
Verwenden Sie keine Klammern, um
assert
wie eine Funktion aufzurufen . Es ist eine Aussage. Wenn Sie dies tun, führenassert(condition, message)
Sie dasassert
mit einem(condition, message)
Tupel als erstem Parameter aus.Wie zum Deaktivieren sie, beim Laufen
python
in optimierten Modus, wo__debug__
istFalse
, werden assert - Anweisungen ignoriert. Übergeben Sie einfach die-O
Flagge:Siehe hier für die entsprechende Dokumentation.
quelle
if not condition: raise AssertError()
, warum sollte ich assert verwenden? Gibt es Bedingungen, unter denen die Behauptung besser ist als nur eine kürzere Form derif not condition
Aussage?if
). Lesen Sie die Dokumente für weitere Informationen :)assert
, aber nachdem ich alle Antworten gelesen habe, habe ich absolut nichts, was ich will!Achten Sie auf die Klammern. Wie oben erwähnt, handelt es sich in Python 3
assert
immer noch um eine Aussage . In Analogieprint(..)
zu kann man das gleiche auf extrapolierenassert(..)
oderraise(..)
Sie sollten es nicht.Dies ist wichtig, weil:
wird im Gegensatz zu nicht funktionieren
Der Grund, warum der erste nicht funktioniert, ist der, der
bool( (False, "Houston we've got a problem") )
ausgewertet wirdTrue
.In der Anweisung
assert(False)
handelt es sich lediglich um redundante KlammernFalse
, die nach ihrem Inhalt ausgewertet werden. Aber mitassert(False,)
den Klammern ist jetzt ein Tupel, und ein nicht leeres Tupel wirdTrue
in einem booleschen Kontext ausgewertet .quelle
assert (2 + 2 = 5), "Houston we've got a problem"
sollte ok sein, ja?assert (2 + 2 = 5), "Houston we've got a problem"
wird nicht funktionieren ... aber es hat nichts mit der assert-Anweisung zu tun, was in Ordnung ist. Ihr Zustand wird nicht funktionieren, weil es kein Zustand ist. Eine Sekunde fehlt=
.Wie andere Antworten festgestellt haben,
assert
ähnelt dies dem Auslösen einer Ausnahme, wenn eine bestimmte Bedingung nicht erfüllt ist. Ein wichtiger Unterschied besteht darin, dass Assert-Anweisungen ignoriert werden, wenn Sie Ihren Code mit der Optimierungsoption kompilieren-O
. Die Dokumentation besagt, dassassert expression
dies besser als gleichwertig beschrieben werden kannDies kann nützlich sein, wenn Sie Ihren Code gründlich testen und dann eine optimierte Version veröffentlichen möchten, wenn Sie froh sind, dass keiner Ihrer Assertionsfälle fehlschlägt. Wenn die Optimierung aktiviert ist, wird die
__debug__
Variable zu False und die Bedingungen werden nicht mehr ausgewertet. Diese Funktion kann Sie auch auffangen, wenn Sie sich auf die Behauptungen verlassen und nicht erkennen, dass sie verschwunden sind.quelle
if Not Error: raise Exception(“ this is a error”)
? Auf diese Weise zeigt das Programm immer noch die Fehlerquelle an, wenn der Benutzer sieassert
Anweisung verwenden? Hierbei wird davon ausgegangen, dass Sie bei der Freigabe des Programms für den Endbenutzer das Flag -O verwenden und somit davon ausgehen, dass alle Fehler behoben wurden. Daher ist jeder Fehler oder Programmabsturz auf eine vertraglich gültige Eingabe in das Programm zurückzuführen, die jedoch vom Programm nicht behandelt werden kann. Daher sollte es den Benutzer als solchen alarmieren.Das Ziel einer Behauptung in Python ist es, Entwickler über nicht behebbare Fehler in einem Programm zu informieren .
Behauptungen sollen keine erwarteten Fehlerzustände wie "Datei nicht gefunden" anzeigen, bei denen ein Benutzer Korrekturmaßnahmen ergreifen (oder es einfach erneut versuchen) kann.
Eine andere Sichtweise ist, zu sagen, dass Behauptungen interne Selbstprüfungen in Ihrem Code sind. Sie funktionieren, indem sie einige Bedingungen in Ihrem Code als unmöglich deklarieren . Wenn diese Bedingungen nicht zutreffen, liegt ein Fehler im Programm vor.
Wenn Ihr Programm fehlerfrei ist, treten diese Bedingungen niemals auf. Aber wenn einer von ihnen tut das Programm auftreten wird mit einer Assertion Fehler abstürzen Sie genau zu sagen , die „unmöglich“ Zustand ausgelöst wurde. Dies macht es viel einfacher, Fehler in Ihren Programmen aufzuspüren und zu beheben.
Hier ist eine Zusammenfassung aus einem Tutorial zu Pythons Behauptungen, die ich geschrieben habe:
quelle
assert
Aussage zu verstehen und wann man sie verwendet. Ich versuche, eine Reihe von Begriffen zu verstehen, die Sie in dem Artikel eingeführt haben.assert store.product_exists(product_id), 'Unknown product id'
ist keine gute Praxis, denn wenn das Debugging deaktiviert ist , kann das Produktuser
auch dannadmin
gelöscht werden, wenn dies nicht der Fall ist. Betrachten Sieassert user.is_admin()
alsunrecoverable
Fehler? Warum ist das nicht einself-check
?assert statement
, kann dies nichtprice
auch als Benutzereingabe betrachtet werden? Warum betrachten Sieassert user.is_admin()
als Datenvalidierung, aber nichtassert price
?Andere haben Ihnen bereits Links zur Dokumentation gegeben.
In einer interaktiven Shell können Sie Folgendes ausprobieren:
Die erste Anweisung bewirkt nichts, während die zweite eine Ausnahme auslöst. Dies ist der erste Hinweis: Asserts sind nützlich, um Bedingungen zu überprüfen, die an einer bestimmten Position Ihres Codes wahr sein sollten (normalerweise der Anfang (Voraussetzungen) und das Ende einer Funktion (Nachbedingungen)).
Behauptungen sind tatsächlich stark an die vertragliche Programmierung gebunden, was eine sehr nützliche technische Praxis ist:
http://en.wikipedia.org/wiki/Design_by_contract .
quelle
Aus Dokumenten:
Hier können Sie mehr lesen: http://docs.python.org/release/2.5.2/ref/assert.html
quelle
Die assert-Anweisung hat zwei Formen.
Die einfache Form
assert <expression>
ist äquivalent zuDie erweiterte Form
assert <expression1>, <expression2>
entsprichtquelle
Behauptungen sind eine systematische Methode, um zu überprüfen, ob der interne Status eines Programms dem vom Programmierer erwarteten entspricht, mit dem Ziel, Fehler zu erkennen. Siehe das folgende Beispiel.
quelle
Hier ist ein einfaches Beispiel: Speichern Sie dies in einer Datei (sagen wir b.py).
und das Ergebnis, wenn
$python b.py
quelle
Wenn die Anweisung nach der Bestätigung wahr ist, wird das Programm fortgesetzt. Wenn die Anweisung nach der Bestätigung jedoch falsch ist, gibt das Programm einen Fehler aus. So einfach ist das.
z.B:
quelle
Die
assert
Anweisung existiert in fast jeder Programmiersprache. Es hilft dabei, Probleme frühzeitig in Ihrem Programm zu erkennen, wenn die Ursache klar ist, und nicht später als Nebeneffekt einer anderen Operation. Sie erwarten immer einenTrue
Zustand.Wenn Sie so etwas tun wie:
Sie weisen das Programm an, diese Bedingung zu testen und sofort einen Fehler auszulösen, wenn er falsch ist.
In Python entspricht der
assert
Ausdruck :Mit dem erweiterten Ausdruck können Sie eine optionale Nachricht übergeben :
Probieren Sie es im Python-Interpreter aus:
Es gibt einige Einschränkungen, die zu beachten sind, bevor sie hauptsächlich für diejenigen verwendet werden, die es für angebracht halten, zwischen den Anweisungen
assert
undif
umzuschalten. Das zu verwendende Zielassert
ist gelegentlich, wenn das Programm eine Bedingung überprüft und einen Wert zurückgibt, der das Programm sofort stoppen soll, anstatt einen alternativen Weg zu finden, um den Fehler zu umgehen:1. Klammern
Wie Sie vielleicht bemerkt haben, verwendet die
assert
Anweisung zwei Bedingungen. Verwenden Sie daher keine Klammern, um sie als offensichtliche Ratschläge zu verwenden. Wenn Sie Folgendes tun:Beispiel:
Sie werden das
assert
mit einem(condition, message)
ausführen, das ein Tupel als ersten Parameter darstellt, und dies geschieht, weil ein nicht leeres Tupel in Python immer istTrue
. Sie können dies jedoch problemlos separat tun:Beispiel:
2. Debug-Zweck
Wenn Sie sich fragen, wann Sie die
assert
Anweisung verwenden sollen. Nehmen Sie ein Beispiel aus dem wirklichen Leben:* Wenn Ihr Programm dazu neigt, jeden vom Benutzer eingegebenen Parameter oder was auch immer zu steuern:
* Ein anderer Fall betrifft die Mathematik, wenn 0 oder nicht positiv als Koeffizient oder Konstante für eine bestimmte Gleichung gilt:
* oder sogar ein einfaches Beispiel für eine boolesche Implementierung:
3. Datenverarbeitung oder Datenvalidierung
Es ist äußerst wichtig, sich nicht auf die
assert
Anweisung zu verlassen, um die Datenverarbeitung oder Datenvalidierung auszuführen, da diese Anweisung bei der Python-Initialisierung mit-O
oder als-OO
Flag (dh als Wert 1, 2 bzw. 0 (als Standard)) oder alsPYTHONOPTIMIZE
Umgebungsvariable deaktiviert werden kann .Wert 1:
* Asserts sind deaktiviert;
* Bytecode-Dateien werden mit der
.pyo
Erweiterung anstelle von generiert.pyc
.*
sys.flags.optimize
wird auf 1 (True
) gesetzt;* und
__debug__
ist auf gesetztFalse
;Wert 2: Deaktiviert ein weiteres Element
* docstrings sind deaktiviert;
Daher ist die Verwendung der
assert
Anweisung zur Validierung einer Art erwarteter Daten äußerst gefährlich und impliziert sogar einige Sicherheitsprobleme. Wenn Sie dann eine Berechtigung validieren müssen, empfehle ich Ihnenraise AuthError
stattdessen. Als vorbedingte Wirksamkeitassert
wird a häufig von Programmierern in Bibliotheken oder Modulen verwendet, bei denen kein Benutzer direkt interagiert.quelle
Wie im C2-Wiki kurz zusammengefasst :
Sie können eine
assert
Anweisung verwenden, um Ihr Verständnis des Codes an einem bestimmten Programmpunkt zu dokumentieren. Beispielsweise können Sie Annahmen oder Garantien zu Eingaben (Voraussetzungen), Programmstatus (Invarianten) oder Ausgaben (Nachbedingungen) dokumentieren.Sollte Ihre Behauptung jemals fehlschlagen, ist dies eine Warnung für Sie (oder Ihren Nachfolger), dass Ihr Verständnis des Programms beim Schreiben falsch war und dass es wahrscheinlich einen Fehler enthält.
Für weitere Informationen hat John Regehr einen wunderbaren Blog-Beitrag über die Verwendung von Behauptungen , der auch für die Python-
assert
Anweisung gilt .quelle
Wenn Sie jemals genau wissen möchten, was eine reservierte Funktion in Python tut, geben Sie ein
help(enter_keyword)
Stellen Sie sicher, dass Sie ein reserviertes Schlüsselwort als Zeichenfolge eingeben, wenn Sie es eingeben.
quelle
Python Assert ist im Grunde eine Debugging-Hilfe, die die Bedingung für die interne Selbstprüfung Ihres Codes testet. Assert macht das Debuggen wirklich einfach, wenn Ihr Code in unmögliche Randfälle gerät. Überprüfen Sie diese unmöglichen Fälle.
Angenommen, es gibt eine Funktion zum Berechnen des Artikelpreises nach Rabatt:
Hier kann discounted_price niemals kleiner als 0 und größer als der tatsächliche Preis sein. Wenn also die oben genannte Bedingung verletzt wird, löst Assert einen Assertion Error aus, der dem Entwickler hilft, zu erkennen, dass etwas Unmögliches passiert ist.
Ich hoffe es hilft :)
quelle
assert
ist in einem Debugging-Kontext nützlich, sollte jedoch nicht außerhalb eines Debugging-Kontexts verwendet werden.Meine kurze Erklärung lautet:
assert
wird ausgelöst,AssertionError
wenn der Ausdruck falsch ist, andernfalls wird der Code einfach fortgesetzt, und wenn ein Komma vorhanden ist, wird es wie folgt lautenAssertionError: whatever after comma
:raise AssertionError(whatever after comma)
Ein verwandtes Tutorial dazu:
quelle
assert
, aber nicht, wann ein verwendet werden soll (oder nicht)assert
. auch darauf hingewiesen , dass eineassert
behinderte sein kann , wenn__debug__
heißtFalse
sinnvoll wäre.Wenn Sie in Pycharm
assert
zusammen mit zusammenisinstance
den Typ eines Objekts deklarieren, können Sie während des Codierens auf die Methoden und Attribute des übergeordneten Objekts zugreifen. Die automatische Vervollständigung erfolgt automatisch.Angenommen, es
self.object1.object2
handelt sich um einMyClass
Objekt.quelle
Wie in anderen Antworten geschrieben, werden
assert
Anweisungen verwendet, um den Status des Programms an einem bestimmten Punkt zu überprüfen.Ich werde nicht wiederholen, was über zugehörige Nachrichten, Klammern oder
-O
Optionen und__debug__
Konstanten gesagt wurde . Überprüfen Sie auch das Dokument auf Informationen aus erster Hand. Ich werde mich auf Ihre Frage konzentrieren: Was nützt dasassert
? Genauer gesagt, wann (und wann nicht) sollte man verwendenassert
?Die
assert
Anweisungen sind nützlich, um ein Programm zu debuggen, es wird jedoch davon abgeraten, Benutzereingaben zu überprüfen. Ich verwende die folgende Faustregel: Behalte die Behauptungen bei, um zu erkennen, dass dies nicht passieren sollte . Eine Benutzereingabe ist möglicherweise falsch, z. B. ein zu kurzes Kennwort. Dies sollte jedoch nicht der Fall sein. Wenn der Durchmesser eines Kreises nicht doppelt so groß ist wie sein Radius, sollten Sie dies nicht tun .Die meiner Meinung nach interessanteste Verwendung
assert
ist inspiriert von der vertraglichen Programmierung, wie sie von B. Meyer in [Objektorientierte Softwarekonstruktion] ( https://www.eiffel.org/doc/eiffel/Object-Oriented_Software_Construction%) beschrieben wurde 2C_2nd_Edition ) und implementiert in der [Eiffel-Programmiersprache] ( https://en.wikipedia.org/wiki/Eiffel_(programming_language) ). Sie können die vertragliche Programmierung mit derassert
Anweisung nicht vollständig emulieren , aber es ist interessant, die Absicht beizubehalten.Hier ist ein Beispiel. Stellen Sie sich vor, Sie müssen eine
head
Funktion schreiben (wie die [head
Funktion in Haskell] ( http://www.zvon.org/other/haskell/Outputprelude/head_f.html )). Die Spezifikation, die Sie erhalten, lautet: "Wenn die Liste nicht leer ist, geben Sie das erste Element einer Liste zurück". Schauen Sie sich die folgenden Implementierungen an:Und
(Ja, das kann geschrieben werden als
return xs[0] if xs else None
, aber das ist nicht der Punkt) .Wenn die Liste nicht leer ist, haben beide Funktionen das gleiche Ergebnis und dieses Ergebnis ist korrekt:
Daher sind beide Implementierungen (ich hoffe) korrekt. Sie unterscheiden sich, wenn Sie versuchen, das Hauptelement einer leeren Liste zu übernehmen:
Aber:
Auch hier sind beide Implementierungen korrekt, da niemand eine leere Liste an diese Funktionen übergeben sollte (wir sind außerhalb der Spezifikation ). Das ist ein falscher Anruf, aber wenn Sie einen solchen Anruf tätigen, kann alles passieren. Eine Funktion löst eine Ausnahme aus, die andere gibt einen speziellen Wert zurück. Das Wichtigste ist: Wir können uns nicht auf dieses Verhalten verlassen . Wenn
xs
leer ist, funktioniert dies:Dies führt jedoch zum Absturz des Programms:
Um einige Überraschungen zu vermeiden, möchte ich wissen, wann ich ein unerwartetes Argument an eine Funktion übergebe. Mit anderen Worten: Ich würde gerne wissen, wann das beobachtbare Verhalten nicht zuverlässig ist, da es von der Implementierung und nicht von der Spezifikation abhängt. Natürlich kann ich die Spezifikation lesen, aber Programmierer lesen die Dokumente nicht immer sorgfältig.
Stellen Sie sich vor, ich hätte eine Möglichkeit, die Spezifikation in den Code einzufügen, um den folgenden Effekt zu erzielen: Wenn ich gegen die Spezifikation verstoße, z. B. indem
head
ich eine leere Liste an übergebe , erhalte ich eine Warnung. Das wäre eine große Hilfe, um ein korrektes (dh mit der Spezifikation konformes) Programm zu schreiben. Und hierassert
kommt die Szene ins Spiel:Und
Jetzt haben wir:
Und:
Beachten Sie, dass
head1
einAssertionError
, nicht einIndexError
. Dies ist wichtig, daAssertionError
es sich nicht um einen Laufzeitfehler handelt, sondern um einen Verstoß gegen die Spezifikation. Ich wollte eine Warnung, erhalte aber eine Fehlermeldung. Glücklicherweise kann ich die Prüfung deaktivieren (mit der-O
Option), jedoch auf eigenes Risiko. Ich werde es tun, ein Absturz ist wirklich teuer und hoffe auf das Beste. Stellen Sie sich vor, mein Programm ist in ein Raumschiff eingebettet, das durch ein Schwarzes Loch fährt. Ich werde Behauptungen deaktivieren und hoffe, dass das Programm robust genug ist, um nicht so lange wie möglich abzustürzen.In diesem Beispiel ging es nur um Vorbedingungen, mit denen Sie
assert
Nachbedingungen (Rückgabewert und / oder Status) und Invarianten (Status einer Klasse) überprüfen können . Beachten Sie, dass das Überprüfen von Nachbedingungen und Invarianten mitassert
umständlich sein kann:Sie werden nicht so anspruchsvoll sein wie Eiffel, aber Sie können die Gesamtqualität eines Programms verbessern.
Zusammenfassend ist die
assert
Aussage ein bequemer Weg, um zu erkennen, dass dies nicht passieren sollte . Verstöße gegen die Spezifikation (z. B. Weitergabe einer leeren Liste anhead
) sind erstklassig. Dies sollte in Situationen nicht vorkommen. Während dieassert
Anweisung verwendet werden kann, um unerwartete Situationen zu erkennen, ist dies eine privilegierte Möglichkeit, um sicherzustellen, dass die Spezifikation erfüllt wird. Sobald Sieassert
Anweisungen in den Code eingefügt haben , um die Spezifikation darzustellen, können wir hoffen, dass Sie die Qualität des Programms verbessert haben, da falsche Argumente, falsche Rückgabewerte, falsche Zustände einer Klasse ... gemeldet werden.quelle
format: assert Ausdruck [, Argumente] Wenn assert auf eine Anweisung stößt, wertet Python den Ausdruck aus. Wenn die Anweisung nicht wahr ist, wird eine Ausnahme ausgelöst (assertionError). Wenn die Zusicherung fehlschlägt, verwendet Python ArgumentExpression als Argument für den AssertionError. AssertionError-Ausnahmen können wie jede andere Ausnahme mit der try-exception-Anweisung abgefangen und behandelt werden. Wenn sie jedoch nicht behandelt werden, wird das Programm beendet und ein Traceback erstellt. Beispiel:
Wenn der obige Code ausgeführt wird, wird das folgende Ergebnis erzeugt:
quelle
Kann verwendet werden, um sicherzustellen, dass Parameter im Funktionsaufruf übergeben werden.
quelle
if not user_key: raise ValueError()
letzten beidenassert
sollte nicht für die Eingabevalidierung verwendet werden, da entweder die Validierung entfernt wird, wenn dies der Fall__debug__
istFalse
. Die Verwendung von Zusicherungen für Nicht-Debug-Zwecke kann dazu führen, dass Benutzer die resultierendenAssertionError
s abfangen , was das Debuggen schwieriger als weniger macht.quelle
Grundsätzlich bedeutet das Schlüsselwort assert, dass die Bedingung, wenn sie nicht erfüllt ist, durch einen Assertionerror andernfalls beispielsweise in Python fortgesetzt wird.
Code-1
AUSGABE:
Code-2
AUSGABE:
quelle
assert
, aber nicht antwortet , wenn zu verwenden (oder nicht verwenden) einassert
.