In einem Kommentar zu dieser Frage sah ich eine Aussage, die die Verwendung empfahl
result is not None
vs.
result != None
Ich habe mich gefragt, was der Unterschied ist und warum einer dem anderen empfohlen werden könnte.
In einem Kommentar zu dieser Frage sah ich eine Aussage, die die Verwendung empfahl
result is not None
vs.
result != None
Ich habe mich gefragt, was der Unterschied ist und warum einer dem anderen empfohlen werden könnte.
Antworten:
==
ist ein Gleichheitstest . Es wird geprüft, ob die rechte und die linke Seite gleiche Objekte sind (entsprechend ihrer__eq__
oder ihrer__cmp__
Methoden).is
ist ein Identitätstest . Es wird geprüft, ob die rechte und die linke Seite dasselbe Objekt sind. Es werden keine Methodenaufrufe durchgeführt, Objekte können denis
Vorgang nicht beeinflussen .Sie verwenden
is
(undis not
) für Singletons, z. B.None
wenn Sie sich nicht für Objekte interessieren, die dies vorgeben möchten,None
oder wenn Sie sich vor Objekten schützen möchten, die beim Vergleich mit Objekten brechenNone
.quelle
None
hat wenige Methoden und fast keine Attribute. Wenn Ihr__eq__
Test eine Methode oder ein Attribut erwartet hat, ist diese möglicherweise fehlerhaft.def __eq__( self, other ): return self.size == other.size
. Zum Beispiel wird brechen, wennother
zufällig istNone
.is
ist wie Javas==
. Pythons==
ist wie Javas.equals()
. Dies hilft natürlich nur, wenn Sie Java kennen.is
wie===
(sehr gleich) und umgekehrtis not
wie!==
(nicht genau gleich) ist.is not
ein einzelner Operator oder negiert er nur das Ergebnis vonis
intern wienot foo is bar
?Lassen Sie mich zunächst einige Begriffe durchgehen. Wenn Sie nur Ihre Frage beantworten möchten, scrollen Sie nach unten zu "Beantworten Ihrer Frage".
Definitionen
Objektidentität : Wenn Sie ein Objekt erstellen, können Sie es zu einer Variablen zuweisen können. Sie können es dann auch einer anderen Variablen zuweisen. Und ein anderer.
In diesem Fall
cancel
,close
unddismiss
beziehen sich alle auf das gleiche Objekt im Speicher. Sie haben nur einButton
Objekt erstellt, und alle drei Variablen beziehen sich auf dieses eine Objekt. Wir sagen dascancel
,close
unddismiss
alle beziehen sich auf identische Objekte; Das heißt, sie beziehen sich auf ein einzelnes Objekt.Objektgleichheit : Wenn Sie zwei Objekte vergleichen, ist es Ihnen normalerweise egal, dass sie sich auf genau dasselbe Objekt im Speicher beziehen . Mit der Objektgleichheit können Sie Ihre eigenen Regeln für den Vergleich zweier Objekte definieren. Wenn Sie schreiben
if a == b:
, sagen Sie im Wesentlichenif a.__eq__(b):
. Auf diese Weise können Sie eine__eq__
Methode definierena
, mit der Sie Ihre eigene Vergleichslogik verwenden können.Begründung für Gleichstellungsvergleiche
Begründung: Zwei Objekte haben genau die gleichen Daten, sind jedoch nicht identisch. (Sie sind nicht dasselbe Objekt im Speicher.) Beispiel: Strings
Hinweis: Ich verwende hier Unicode-Zeichenfolgen, da Python intelligent genug ist, um reguläre Zeichenfolgen wiederzuverwenden, ohne neue im Speicher zu erstellen.
Hier habe ich zwei Unicode-Strings
a
undb
. Sie haben genau den gleichen Inhalt, aber sie sind nicht das gleiche Objekt im Speicher. Wenn wir sie jedoch vergleichen, möchten wir, dass sie gleich sind. Was hier passiert ist, dass das Unicode-Objekt die__eq__
Methode implementiert hat .Hinweis:
__eq__
onunicode
ist definitiv effizienter implementiert.Begründung: Zwei Objekte haben unterschiedliche Daten, werden jedoch als dasselbe Objekt betrachtet, wenn einige Schlüsseldaten identisch sind. Beispiel: Die meisten Arten von Modelldaten
Hier habe ich zwei Dell-Monitore
a
undb
. Sie haben die gleiche Marke und das gleiche Modell. Sie haben jedoch weder dieselben Daten noch dasselbe Objekt im Speicher. Wenn wir sie jedoch vergleichen, möchten wir, dass sie gleich sind. Was hier passiert, ist, dass das Monitor-Objekt die__eq__
Methode implementiert hat .Beantwortung Ihrer Frage
None
Verwenden Sie im Vergleich zu immeris not
. Keiner ist ein Singleton in Python - es gibt immer nur eine Instanz davon im Speicher.Durch den Vergleich der Identität kann dies sehr schnell durchgeführt werden. Python prüft, ob das Objekt, auf das Sie sich beziehen, dieselbe Speicheradresse wie das globale None-Objekt hat - ein sehr, sehr schneller Vergleich zweier Zahlen.
Durch den Vergleich der Gleichheit muss Python nachschlagen, ob Ihr Objekt über eine
__eq__
Methode verfügt. Ist dies nicht der Fall, wird jede Oberklasse auf der Suche nach einer__eq__
Methode untersucht. Wenn es eines findet, ruft Python es auf. Dies ist besonders schlimm, wenn die__eq__
Methode langsam ist und nicht sofort zurückkehrt, wenn sie bemerkt, dass das andere Objekt istNone
.Haben Sie nicht implementiert
__eq__
? Dann wird Python wahrscheinlich die__eq__
Methode findenobject
und diese stattdessen verwenden - die ohnehin nur die Objektidentität überprüft.Wenn Sie die meisten anderen Dinge in Python vergleichen, werden Sie verwenden
!=
.quelle
Folgendes berücksichtigen:
quelle
None
ist ein Singleton, daher funktioniert der Identitätsvergleich immer, während ein Objekt den Gleichheitsvergleich über vortäuschen kann.__eq__()
.quelle
None
, aber falsches Verhalten in Bezug aufNone
könnte als Nebeneffekt der Implementierung von Gleichheit gegen andere Typen auftreten. Es sind weniger Auswirkungen auf die Sicherheit als vielmehr Auswirkungen auf die Korrektheit.Einige Objekte sind Singletons und entsprechen daher
is
mit ihnen==
. Die meisten sind es nicht.quelle
()
und1
sind nicht von Natur aus Singletons.-NSMALLNEGINTS <= n <= NSMALLPOSINTS
) und leere Tupel sind Singletons. Es ist zwar weder dokumentiert noch garantiert, aber es ist unwahrscheinlich, dass es sich ändert.