Kann ich benutzen:
if A:
anstatt
if A is not None:
Letzteres scheint so ausführlich. Ist da ein Unterschied?
Die Aussage
if A:
ruft auf A.__nonzero__()
(siehe Dokumentation zu speziellen Methodennamen ) und verwendet den Rückgabewert dieser Funktion. Hier ist die Zusammenfassung:
object.__nonzero__(self)
Wird aufgerufen, um Wahrheitswerttests und den eingebauten Betrieb zu implementieren
bool()
. sollte zurückgebenFalse
oder oderTrue
oder ihre ganzzahligen Äquivalente0
oder1
. Wenn diese Methode nicht definiert ist,__len__()
wird sie aufgerufen, wenn sie definiert ist, und das Objekt wird als wahr betrachtet, wenn sein Ergebnis ungleich Null ist. Wenn eine Klasse weder__len__()
noch definiert__nonzero__()
, werden alle ihre Instanzen als wahr betrachtet.
Andererseits,
if A is not None:
vergleicht nur die Referenz A
mit None
, um festzustellen, ob sie gleich ist oder nicht.
A is not None
ist schneller, da es viel weniger Arbeit zu tun gibtif object(): pass
beträgt ~ 0,130 usec pro Schleife, währendif object() is not None: pass
~ 0,135 usec beträgt. Auf jeden Fall sollten Sie nicht die Leistung verwenden, um zwischen diesen beiden zu wählen, sondern die Unterschiede in ihrer Funktionsweise betrachten, da sie nicht gleichwertig sind .if A is not None
scheint langsamer zu sein, da es sich um einen Vergleich handelt und der eingebaute SingletonNone
als Zwischenschritt zum Vergleichen geladen werden mussA
(siehedis.dis()
). Korrigieren Sie mich, wenn ich falschif A:
liege, aber effizienter zu sein scheint, sobald Sie wirklich den Wahrheitswert und nicht dieNone
Identität testen möchten.python -m timeit -s"a=0" "if a: pass" "else: pass"
ist schneller als,python -m timeit -s"a=0" "if a is None: pass" "else: pass"
aberpython -m timeit -s"a=1" "if a: pass" "else: pass"
langsamer. Könnte plattformabhängig sein, sehen Sie, ob Sie die gleichen Ergebnisse erhaltenis None
Test war in der Tat der langsamste für mich. In Pypy haben sie alle genau das gleiche gemessen :)Wie in PEP8 geschrieben :
quelle
None
, sondern nur für eine Wahrheitsprüfung. In diesem Fallif A:
scheint es effizienter zu sein (nehmen Sie adis.dis()
, es gibt die zusätzlichen Schritte zum Laden des eingebautenNone
und Vergleichens mitif A is not None:
, während esjump_if
im anderen Fall nur a gibt ).so ist es nicht dasselbe wie
quelle
Viele Funktionen geben None zurück, wenn keine geeigneten Ergebnisse vorliegen. Beispielsweise gibt die
.first()
Methode einer SQLAlchemy-Abfrage None zurück, wenn das Ergebnis keine Zeilen enthält. Angenommen, Sie haben einen Wert ausgewählt, der möglicherweise 0 zurückgibt, und müssen wissen, ob er tatsächlich 0 ist oder ob die Abfrage überhaupt keine Ergebnisse erzielt hat.Eine gebräuchliche Redewendung besteht darin, dem optionalen Argument einer Funktion oder Methode den Standardwert None zu geben und dann zu testen, ob dieser Wert None ist, um festzustellen, ob er angegeben wurde. Beispielsweise:
Vergleiche das mit:
Was passiert in letzterem Fall, wenn Sie anrufen
spam(0)
oderspam([])
? Die Funktion erkennt (fälschlicherweise), dass Sie keinen Wert für übergeben haben,eggs
und berechnet einen Standardwert für Sie. Das ist wahrscheinlich nicht was du willst.Oder stellen Sie sich eine Methode wie "Rückgabe der Liste der Transaktionen für ein bestimmtes Konto" vor. Wenn das Konto nicht vorhanden ist, wird möglicherweise None zurückgegeben. Dies unterscheidet sich von der Rückgabe einer leeren Liste (was bedeuten würde, dass "dieses Konto existiert, aber keine Transaktionen aufgezeichnet hat").
Zum Schluss zurück zum Datenbankmaterial. Es gibt einen großen Unterschied zwischen NULL und einer leeren Zeichenfolge. Eine leere Zeichenfolge sagt normalerweise "hier gibt es einen Wert, und dieser Wert ist überhaupt nichts". NULL sagt "Dieser Wert wurde nicht eingegeben."
In jedem dieser Fälle möchten Sie verwenden
if A is None
. Sie suchen nach einem bestimmten Wert - Keine - und nicht nur nach einem Wert, der zufällig in "Falsch" umgewandelt wird.quelle
Sie machen sehr unterschiedliche Dinge .
Die unten überprüft , ob A hat nichts außer den Werten
False
,[]
,None
,''
und0
. Es überprüft den Wert von A.Im Folgenden wird überprüft, ob A ein anderes Objekt als None ist. Es überprüft und vergleicht die Referenz (Speicheradresse) von A und None.
UPDATE: Weitere Erklärung
Oft scheinen die beiden dasselbe zu tun, so dass viele Leute sie austauschbar verwenden - das ist eine wirklich schlechte Idee. Der Grund, warum die beiden die gleichen Ergebnisse liefern, ist oft ein reiner Zufall aufgrund von Optimierungen des Interpreters / Compilers wie Internierung oder etwas anderem.
Unter Berücksichtigung dieser Optimierungen verwenden Ganzzahlen und Zeichenfolgen mit demselben Wert denselben Speicherplatz. Das erklärt wahrscheinlich, warum zwei separate Zeichenfolgen so wirken, als wären sie gleich.
Andere Dinge verhalten sich jedoch nicht gleich.
Die beiden Listen haben eindeutig ein eigenes Gedächtnis. Überraschenderweise verhalten sich Tupel wie Strings.
Dies liegt wahrscheinlich daran, dass sich Tupel garantiert nicht ändern. Daher ist es sinnvoll, denselben Speicher wiederzuverwenden.
Fazit: Sie können sich nicht auf Zufälle verlassen . Nur weil es wie eine Ente quakt, heißt das nicht, dass es eine Ente ist. Verwenden Sie
is
und==
je nachdem, was Sie wirklich überprüfen möchten. Diese Dinge können schwer zu debuggen sein, da sie sichis
wie eine Prosa lesen, die wir oft nur überfliegen.quelle
None
ist ein Singleton, es ist kein Implementierungsdetail (im Gegensatz zu int oder string interning). Ich bin mir nicht sicher, ob ich dem folge, was du meinst.None
sich das anders verhält alsint
oderstr
aufgrund von Internierung. Mein Punkt ist dasis
und==
ich überprüfe verschiedene Dinge; überprüft zuerst eine Speicheradresse, die zweite überprüft den Inhalt von Speicheradressen.if A:
wird sich als falsch erweisen, wenn A 0, Falsch, leere Zeichenfolge, leere Liste oder Keine ist, was zu unerwünschten Ergebnissen führen kann.quelle
Die meisten Anleitungen, die ich gesehen habe, empfehlen, dass Sie verwenden sollten
wenn eine:
es sei denn, Sie haben einen Grund, genauer zu sein.
Es gibt einige geringfügige Unterschiede. Es gibt andere Werte als None, die False zurückgeben, z. B. leere Listen oder 0. Überlegen Sie sich also, worauf Sie wirklich testen.
quelle
None ist ein spezieller Wert in Python, der normalerweise eine nicht initialisierte Variable bezeichnet. Um zu testen, ob A diesen bestimmten Wert nicht hat, verwenden Sie:
Falsey-Werte sind eine spezielle Klasse von Objekten in Python (z. B. false, []). Um zu testen, ob A falsch ist, verwenden Sie:
Daher sind die beiden Ausdrücke nicht gleich. Und Sie sollten sie besser nicht als Synonyme behandeln.
PS Keine ist auch falsch, daher impliziert der erste Ausdruck den zweiten. Aber der zweite behandelt neben None noch andere Falsey-Werte. Nun ... wenn Sie sicher sein können, dass Sie in None keine anderen Falsey-Werte als None haben können, können Sie den ersten Ausdruck durch den zweiten ersetzen.
quelle
Das hängt vom Kontext ab.
Ich verwende es,
if A:
wenn ich eineA
Art Sammlung erwarte , und ich möchte den Block nur ausführen, wenn die Sammlung nicht leer ist. Auf diese Weise kann der Anrufer jede gut erzogene Sammlung übergeben, ob leer oder nicht, und sie das tun lassen, was ich erwarte. Es ermöglichtNone
undFalse
unterdrückt auch die Ausführung des Blocks, was gelegentlich zum Aufrufen von Code geeignet ist.OTOH, wenn ich erwarte , dass
A
einige völlig beliebiges Objekt sein , aber es Verzug geraten hätte zuNone
, dann habe ich immer verwendenif A is not None
, als Code aufrufen absichtlich einen Verweis auf eine leere Sammlung, leeren String oder ein 0-wertigen numerischen Typ bestanden haben könnte, oder Boolescher WertFalse
oder eine Klasseninstanz, die im booleschen Kontext falsch ist.Auf der anderen Seite, wenn ich erwarte
A
, dass es sich um eine spezifischere Sache handelt (z. B. eine Instanz einer Klasse, deren Methoden ich aufrufen werde), die jedochNone
standardmäßig verwendet werden könnte , und ich betrachte die standardmäßige boolesche Konvertierung als a Eigentum der Klasse Es macht mir nichts aus, alle Unterklassen durchzusetzen, dann erspare ichif A:
meinen Fingern nur die schreckliche Last, zusätzliche 12 Zeichen einzugeben.quelle
Ich habe eine Datei namens erstellt
test.py
und sie auf dem Interpreter ausgeführt. Sie können ändern, was Sie möchten, um sicherzugehen, wie sich die Dinge hinter den Kulissen entwickeln.Dies ist der Assembler-Unterschied:
Quelle:
quelle
Ersteres ist mehr Pythonic (besserer ideomatischer Code), führt den Block jedoch nicht aus, wenn A False ist (nicht None).
quelle
is/is not None
. Nach PEP8 folgt Pythonic. Außerdem sind die beiden Tests unterschiedlich .Python> = 2,6,
wenn wir schreiben wie
generiert eine Warnung als,
Also können wir verwenden
quelle