Python Kein Vergleich: Soll ich "is" oder == verwenden?

212

Mein Editor warnt mich beim Vergleichen my_var == None, aber keine Warnung bei der Verwendung my_var is None.

Ich habe einen Test in der Python-Shell durchgeführt und festgestellt, dass beide eine gültige Syntax sind, aber mein Editor scheint zu sagen, dass dies my_var is Nonebevorzugt wird.

Ist dies der Fall und wenn ja, warum?

Clay Wardell
quelle
7
PEP 8 sagt irgendwo, dass Sie mit Singletons vergleichen sollten, indem Sie is- python.org/dev/peps/pep-0008/#programming-recommendations
Volatility
2
In diesem Poster geht es um Python 3, und meine Frage bezieht sich auf Python 2.x. Ich bin mir nicht sicher, ob dies ein ausreichend großer Unterschied ist, um beide verbleibenden zu rechtfertigen, aber ich habe die Frage so bearbeitet, dass sie dies nur für den Fall enthält.
Clay Wardell
2
Ich denke nicht, dass diese Frage wirklich ein Duplikat ist. Der andere war ungefähr == vs ist im Allgemeinen, dieser ist ungefähr keiner im Besonderen.
IJ Kennedy

Antworten:

253

Zusammenfassung:

Verwenden isSie diese Option, wenn Sie die Identität eines Objekts überprüfen möchten (z. B. prüfen, ob dies der Fall varist None). Verwenden ==Sie diese Option, wenn Sie die Gleichheit überprüfen möchten (z. B. Ist vargleich 3?).

Erläuterung:

Sie können benutzerdefinierte Klassen haben, in die zurückgegeben my_var == NonewirdTrue

z.B:

class Negator(object):
    def __eq__(self,other):
        return not other

thing = Negator()
print thing == None    #True
print thing is None    #False

isKontrollen für die Objektidentität . Es gibt nur 1 Objekt None. Wenn Sie dies tun my_var is None, prüfen Sie, ob es sich tatsächlich um dasselbe Objekt handelt (nicht nur um gleichwertige Objekte).

Mit anderen Worten, es ==handelt sich um eine Prüfung auf Äquivalenz (die von Objekt zu Objekt definiert wird), während isauf Objektidentität geprüft wird:

lst = [1,2,3]
lst == lst[:]  # This is True since the lists are "equivalent"
lst is lst[:]  # This is False since they're actually different objects
mgilson
quelle
22
Wann unterscheidet is Nonesich von == None?
Blender
11
@Blender Im genannten Fall. __eq__kann auf irgendeine Weise definiert werden, aber das Verhalten von iskann nicht so einfach geändert werden.
Lev Levitsky
5
@LevLevitsky: Eine der Beispielanwendungen von Mython war "die Protokolle so zu erweitern, dass jeder Operator sogar überlastet werden kann is". Nach einem Kommentar zu den Listen änderte er dies in "... sogar is(aber nur, wenn Sie verrückt sind)."
Abarnert
1
+1, aber es wäre noch besser, wenn diese Antwort die PEP 8-Referenz enthalten würde, die die anderen machen (und erklären, warum die Entscheidung hinter PEP 8 sinnvoll ist, was sie bereits tut).
Abarnert
3
@abarnert - Mir war nicht einmal bewusst, dass PEP 8 hier eine Empfehlung abgegeben hat. Der Punkt ist, dass sie verschiedene Operatoren sind, die verschiedene Dinge tun. Es kann Fälle geben , wo object == Noneeigentlich ist das richtige Idiom (obwohl ich nicht von jedem aus der Spitze von meinem Kopf denken kann). Sie müssen nur wissen, was Sie tun.
mgilson
127

iswird im Allgemeinen bevorzugt, wenn beliebige Objekte mit Singletons verglichen werden, Noneda dies schneller und vorhersehbarer ist. isvergleicht immer nach Objektidentität, während das, was zu ==tun ist, vom genauen Typ der Operanden und sogar von ihrer Reihenfolge abhängt.

Diese Empfehlung wird von PEP 8 unterstützt , in dem ausdrücklich festgelegt wird, dass "Vergleiche mit Singletons wie None immer mit isoder is notniemals mit den Gleichheitsoperatoren durchgeführt werden sollten".

user4815162342
quelle
6
Vielen Dank für die Veröffentlichung; Die akzeptierte Antwort macht einige interessante Punkte, aber Ihre antwortet viel direkter auf die Frage.
Luke Davis
Es scheint seltsam, sich auf ein Implementierungsdetail zu verlassen. Warum sollte es mich interessieren, wie viele Instanzen von NoneType es gibt?
BallpointBen
@BallpointBen Da es sich nicht um ein Implementierungsdetail handelt, befindet sich Noneunter der globalen Konstante nur ein Objekt None. Wenn überhaupt, das NoneTypeist eine Implementierung Detail , weil die NoneSingleton haben muss etwas Art. (Die Tatsache, dass Sie keine Instanzen dieses Typs erstellen können, ist ein guter Hinweis darauf, dass die eine Instanz ein Singleton sein soll.)
user4815162342
@BallpointBen Ich denke, der entscheidende Punkt ist, dass Python ein starkes Konzept der Objektidentität besitzt. Wenn Sie prüfen möchten , ob ein Objekt vergleicht gleich zu None, mit allen Mitteln verwenden obj == None. Wenn Sie überprüfen möchten, ob es sich um ein Objekt handelt None , verwenden Sie obj is None. Der Sinn der PEP 8-Empfehlung (und dieser Antwort) ist, dass die meisten Leute Letzteres wollen, wenn sie nach Keine suchen wollen, und es ist auch schneller und klarer.
user4815162342
Noneunterscheidet sich auch von zwischengespeicherten Objekten wie 0und anderen kleinen Ganzzahlen, bei denen das Caching wirklich ein Implementierungsdetail ist. Der Unterschied besteht darin, dass eine Ganzzahl einen inneren Wert hat, der ihre Eigenschaften angibt und berechnet werden kann. Auf der anderen Seite Nonehat es überhaupt keinen Zustand, es ist nur seine Identität , die zählt und es zu etwas Besonderem macht.
user4815162342
11

PEP 8 definiert, dass es besser ist, den isOperator beim Vergleichen von Singletons zu verwenden.

Thorsten Kranz
quelle