Was ist der Unterschied zwischen "ist keine" und "== keine"

324

Ich bin kürzlich auf diese Syntax gestoßen, ich bin mir des Unterschieds nicht bewusst.

Ich würde es begrüßen, wenn mir jemand den Unterschied sagen könnte.

myusuf3
quelle
1
Beantwortet das deine Frage? Gibt es einen Unterschied zwischen "==" und "ist"?
Juni
Es ist unklar, ob es bei dieser Frage um isvs ==geht oder um die Art dessen, was genau Noneist und wie sich das Verhalten in beiden Kontexten unterscheidet (letzteres ist der Grund, warum ich hier gelandet bin). Aufgrund der Unbestimmtheit und des Mangels an OP-Antworten ... bin ich überrascht, dass dies so viele positive Stimmen hat. Ich meine ... cmon ... die Frage ist nicht einmal in der eigentlichen Frage geschrieben ...
RTbecard

Antworten:

290

Die Antwort wird hier erklärt .

Zitieren:

Es steht einer Klasse frei, Vergleiche nach Belieben zu implementieren, und sie kann festlegen, dass Vergleiche mit None etwas bedeuten (was tatsächlich Sinn macht; wenn Ihnen jemand sagt, dass Sie das None-Objekt von Grund auf neu implementieren sollen, wie würden Sie es sonst dazu bringen, True zu vergleichen gegen sich selbst?).

In der Praxis gibt es keinen großen Unterschied, da benutzerdefinierte Vergleichsoperatoren selten sind. Aber Sie sollten in der is NoneRegel verwenden.

Ben Hoffstein
quelle
57
Auch is Noneist ein bisschen (~ 50%) schneller als == None:)
Nas Banov
26
@ myusuf3: >>> timeit.Timer ('None is None'). timeit () | 0,225 | >>> timeit.Timer ('None == None'). timeit () | 0,328
Nas Banov
9
@ myusuf3 Dafür brauchst du eigentlich keinen Beweis. isist im Grunde ein ganzzahliger Vergleich, bei dem ==nicht nur Referenzen aufgelöst werden, sondern auch Werte verglichen werden, die möglicherweise nicht übereinstimmende Typen aufweisen.
Pijusn
4
Einer für "ist". Wenn eine Variable entweder None oder etwas sein kann, das keinen aussagekräftigen Vergleich mit None hat. Zum Beispiel kann eine Variable ein numpy.array oder None sein (mein spezieller Fall).
Jblasco
3
Ich möchte hinzufügen, was @TimLudwinski sagt: Wenn jemand den Gleichheitsoperator überschreiben möchte, um None zu einem Sonderfall zu machen, warum sollten wir ihm dann etwas anderes sagen? Zweitens: "Es sollte einen - und vorzugsweise nur einen - offensichtlichen Weg geben, dies zu tun." Und der offensichtliche Weg, um zu überprüfen, ob etwas gleich etwas ist, ist der Gleichheitsoperator.
Yuval
162
class Foo:
    def __eq__(self,other):
        return True
foo=Foo()

print(foo==None)
# True

print(foo is None)
# False
unutbu
quelle
So einfach zu verstehen mit einem guten Beispiel, danke dafür!
Basj
56

In diesem Fall sind sie gleich. Noneist ein Singleton-Objekt (es gibt immer nur eines None).

is prüft, ob das Objekt dasselbe Objekt ist, während == nur prüft, ob sie gleichwertig sind.

Zum Beispiel:

p = [1]
q = [1]
p is q # False because they are not the same actual object
p == q # True because they are equivalent

Aber da es nur einen gibt None, werden sie immer gleich sein und isTrue zurückgeben.

p = None
q = None
p is q # True because they are both pointing to the same "None"
Donald Miner
quelle
17
Diese Antwort ist nicht korrekt, wie in Ben Hoffsteins Antwort unter stackoverflow.com/questions/3257919/is-none-vs-none/… erläutert . x == Nonekann Trueauch dann auswerten, wenn xes sich Nonenur um eine Instanz einer Klasse mit einem eigenen benutzerdefinierten Gleichheitsoperator handelt.
Max
5

Wenn Sie numpy verwenden,

if np.zeros(3)==None: pass

gibt einen Fehler aus, wenn numpy einen elementweisen Vergleich durchführt

jf328
quelle
3

Es hängt davon ab, was Sie mit None vergleichen. Einige Klassen verfügen über benutzerdefinierte Vergleichsmethoden, die == Noneanders behandelt werden als is None.

Insbesondere muss die Ausgabe von a == None nicht einmal boolesch sein !! - eine häufige Ursache für Fehler.

Nehmen Sie für ein bestimmtes Beispiel ein Numpy-Array, in dem der ==Vergleich elementweise implementiert wird:

import numpy as np
a = np.zeros(3) # now a is array([0., 0., 0.])
a == None #compares elementwise, outputs array([False, False, False]), i.e. not boolean!!!
a is None #compares object to object, outputs False
PGlivi
quelle