Gibt es einen Unterschied zwischen:
if foo is None: pass
und
if foo == None: pass
Die Konvention, die ich in den meisten Python-Codes gesehen habe (und den Code, den ich selbst schreibe), ist die erstere, aber ich bin kürzlich auf Code gestoßen, der den letzteren verwendet. None ist eine Instanz (und die einzige Instanz, IIRC) von NoneType, also sollte es keine Rolle spielen, oder? Gibt es Umstände, unter denen dies der Fall sein könnte?
is
Operator nicht angepasst werden kann (überladen durch eine benutzerdefinierte Klasse).__eq__(self)
ist eine spezielle integrierte Methode, die bestimmt, wie==
mit einem Python-Objekt umgegangen wird . Hier haben wir es überschrieben, damit es bei==
Verwendung für Objekte vom TypFoo
immer true zurückgibt. Es gibt keine äquivalente Methode für denis
Operator und daher kann das Verhalten vonis
nicht auf die gleiche Weise geändert werden.Möglicherweise möchten Sie diese Objektidentität und -äquivalenz lesen .
Die Anweisung 'is' wird für die Objektidentität verwendet und prüft, ob Objekte auf dieselbe Instanz verweisen (gleiche Adresse im Speicher).
Und die '==' Anweisung bezieht sich auf Gleichheit (gleicher Wert).
quelle
a=1;b=1;print(a is b) # True
. Irgendeine Idee, waruma is b
sich herausstellt, dass es wahr ist, selbst wenn es sich um zwei verschiedene Objekte handelt (unterschiedliche Adresse im Speicher)?Ein Wort der Vorsicht:
Ist nicht genau das gleiche wie:
Ersteres ist ein Boolescher Wertetest und kann in verschiedenen Kontexten als falsch bewertet werden. Es gibt eine Reihe von Dingen, die in einem Booleschen Wertestest falsch darstellen, z. B. leere Container oder Boolesche Werte. Keiner wird in dieser Situation ebenfalls als falsch bewertet, aber auch andere Dinge.
quelle
(ob1 is ob2)
gleich(id(ob1) == id(ob2))
quelle
is
Version benötigt keinen Funktionsaufruf und überhaupt keine Suche nach Python-Interpreter-Attributen. Der Dolmetscher kann sofort antworten, ob ob1 tatsächlich ob2 ist.{} is {}
ist falsch undid({}) == id({})
kann (und ist in CPython) wahr sein. Siehe stackoverflow.com/questions/3877230Der Grund dafür
foo is None
ist, dass Sie möglicherweise ein Objekt behandeln, das sein eigenes__eq__
definiert und das Objekt so definiert , dass es gleich None ist. Verwendenfoo is None
Sie es also immer, wenn Sie sehen möchten, ob es infakt istNone
.quelle
Es gibt keinen Unterschied, da identische Objekte natürlich gleich sind. In PEP 8 heißt es jedoch eindeutig, dass Sie Folgendes verwenden sollten
is
:quelle
is
Identitätsprüfungen, nicht Gleichheit. Für Ihre Aussagefoo is none
vergleicht Python einfach die Speicheradresse von Objekten. Es bedeutet, dass Sie die Frage stellen: "Habe ich zwei Namen für dasselbe Objekt?"==
andererseits Tests nach Gleichheit, wie durch die__eq__()
Methode bestimmt. Identität ist ihm egal.None
ist ein Singleton-Operator. SoNone is None
ist es immer wahr.quelle
Für None sollte es keinen Unterschied zwischen Gleichheit (==) und Identität (is) geben. Der NoneType gibt wahrscheinlich Identität für Gleichheit zurück. Da None die einzige Instanz ist, die Sie mit NoneType erstellen können (ich denke, das ist wahr), sind die beiden Operationen gleich. Bei anderen Typen ist dies nicht immer der Fall. Beispielsweise:
Dies würde "Gleich" ausgeben, da Listen eine Vergleichsoperation haben, die nicht die Standardrückgabe der Identität ist.
quelle
@ Jason :
Ich mag es nicht, "if foo:" zu verwenden, es sei denn, foo repräsentiert wirklich einen booleschen Wert (dh 0 oder 1). Wenn foo eine Zeichenfolge oder ein Objekt oder etwas anderes ist, funktioniert "if foo:" möglicherweise, aber es sieht für mich nach einer faulen Verknüpfung aus. Wenn Sie überprüfen, ob x Keine ist, sagen Sie "Wenn x Keine ist:".
quelle
if foo
wird false zurückgegeben und der Kommentar#foo is None
ist falsch.Einige weitere Details:
Die
is
Klausel prüft tatsächlich, ob sich die beidenobject
s am selben Speicherort befinden oder nicht. dh ob beide auf denselben Speicherort zeigen und denselben habenid
.Als Konsequenz von 1 wird
is
sichergestellt, ob die beiden lexikalisch dargestelltenobject
s identische Attribute (Attribute von Attributen ...) haben oder nichtInstanziierung von primitiven Typen wie
bool
,int
,string
(mit einigen Ausnahmen),NoneType
wird in der gleichen Speicherstelle immer einen gleichen Wert aufweist.Z.B
Und da
NoneType
nur eine Instanz von sich selbst in der "Nachschlagetabelle" des Pythons enthalten sein kann, sind erstere und letztere eher ein Programmierstil des Entwicklers, der den Code geschrieben hat (möglicherweise aus Gründen der Konsistenz), als einen subtilen logischen Grund dafür wähle eins über das andere.quelle
some_string is "bar"
, um Zeichenfolgen zu vergleichen. Es gibt keinen einzigen akzeptablen Grund dafür und es wird brechen, wenn Sie es nicht erwarten. Die Tatsache, dass es oft funktioniert, liegt einfach daran, dass CPython weiß, dass es dumm wäre, zwei unveränderliche Objekte mit demselben Inhalt zu erstellen. Aber es kann trotzdem passieren.int
, oder?John Machins Schlussfolgerung, dass
None
es sich um einen Singleton handelt, wird durch diesen Code gestützt.Da
None
ist ein Singletonx == None
undx is None
hätte das gleiche Ergebnis. Meiner ästhetischen Meinung nachx == None
ist es jedoch am besten.quelle
None
Objekt genau das Objekt ist. Im Vergleich dazu sieht man selten, dass None in einem anderen Kontext verwendet wird, außer dass es ähnlichFalse
ist, wenn andere Werte wahr sind. In diesen Fällen ist es idiomatischer, so etwas wieif x: pass
quelle