Ich habe ein Python-Programm, in dem zwei Variablen auf den Wert gesetzt sind 'public'
. In einem bedingten Ausdruck habe ich den Vergleich, var1 is var2
der fehlschlägt, aber wenn ich ihn ändere, wird var1 == var2
er zurückgegeben True
.
Wenn ich jetzt meinen Python-Interpreter öffne und den gleichen "Ist" -Vergleich mache, ist dies erfolgreich.
>>> s1 = 'public'
>>> s2 = 'public'
>>> s2 is s1
True
Was fehlt mir hier?
input = raw_input("Decide (y/n): ")
. B.: . In diesem Fall gibt eine Eingabe von "y" undif input == 'y':
"True" zurück, während "if input is 'y':
False " zurückgegeben wird.Antworten:
is
ist Identitätsprüfung,==
ist Gleichheitstest. Was in Ihrem Code passiert, wird im Interpreter folgendermaßen emuliert:Kein Wunder also, dass sie nicht gleich sind, oder?
Mit anderen Worten:
is
ist dieid(a) == id(b)
quelle
==
vs.equals()
in Java. Das Beste daran ist, dass Python==
nicht mit Java vergleichbar ist==
.None
Wert. Es hat also immer die gleiche ID.Andere Antworten hier sind richtig:
is
wird für den Identitätsvergleich verwendet , während==
sie für den Gleichheitsvergleich verwendet wird . Da Sie sich für Gleichheit interessieren (die beiden Zeichenfolgen sollten dieselben Zeichen enthalten), ist deris
Operator in diesem Fall einfach falsch und Sie sollten==
stattdessen verwenden.Der Grund, warum
is
interaktiv funktioniert, ist, dass (die meisten) Zeichenfolgenliterale standardmäßig interniert sind . Aus Wikipedia:Wenn Sie also zwei Zeichenfolgenliterale (Wörter, die buchstäblich in Ihren Programmquellcode eingegeben werden und von Anführungszeichen umgeben sind) in Ihrem Programm haben, die denselben Wert haben, werden die Zeichenfolgen vom Python-Compiler automatisch interniert, sodass beide gleichzeitig gespeichert werden Speicherort. (Beachten Sie, dass dies nicht immer der Fall ist Fall ist und die Regeln dafür ziemlich kompliziert sind. Verlassen Sie sich daher bitte nicht auf dieses Verhalten im Produktionscode!)
Da in Ihrer interaktiven Sitzung beide Zeichenfolgen tatsächlich am selben Speicherort gespeichert sind, haben sie dieselbe Identität , sodass der
is
Bediener wie erwartet arbeitet. Wenn Sie jedoch eine Zeichenfolge mit einer anderen Methode erstellen (auch wenn diese Zeichenfolge genau dieselben Zeichen enthält), ist die Zeichenfolge möglicherweise gleich , aber nicht dieselbe Zeichenfolge - das heißt, sie hat eine andere Identität , weil sie es ist an einem anderen Ort im Speicher gespeichert.quelle
==
undis
basierend auf der Art der gewünschten Prüfung zu wählen . Wenn Sie sich dafür interessieren, dass die Zeichenfolgen gleich sind (dh denselben Inhalt haben), sollten Sie immer verwenden==
. Wenn Sie sich darum kümmern, ob zwei Python-Namen auf dieselbe Objektinstanz verweisen, sollten Sie verwendenis
. Du brauchst vielleichtis
wenn Sie Code schreiben, der viele verschiedene Werte verarbeitet, ohne sich um deren Inhalt zu kümmern, oder wenn Sie wissen, dass es nur einen von etwas gibt und Sie andere Objekte ignorieren möchten, die so tun, als wären sie das. Wenn Sie sich nicht sicher sind, wählen Sie immer==
.Das
is
Schlüsselwort ist ein Test für die Objektidentität und==
ein Wertevergleich.Wenn Sie verwenden
is
, ist das Ergebnis genau dann wahr, wenn das Objekt dasselbe Objekt ist. Dies gilt==
jedoch immer dann, wenn die Werte des Objekts gleich sind.quelle
Als letztes müssen Sie die
sys.intern
Funktion verwenden, um sicherzustellen, dass Sie einen Verweis auf dieselbe Zeichenfolge erhalten:Wie oben erwähnt, sollten Sie nicht verwenden
is
, um die Gleichheit von Zeichenfolgen zu bestimmen. Dies kann jedoch hilfreich sein, um zu wissen, ob Sie eine seltsame Anforderung habenis
.Beachten Sie, dass die
intern
Funktion früher in Python 2 integriert war, abersys
in Python 3 in das Modul verschoben wurde .quelle
is
ist Identitätstest,==
ist Gleichheitstest. Dies bedeutet, dass auf dieseis
Weise überprüft werden kann, ob zwei Dinge gleich oder nur gleichwertig sind.Angenommen, Sie haben ein einfaches
person
Objekt. Wenn es 'Jack' heißt und '23' Jahre alt ist, entspricht es einem anderen 23 Jahre alten Jack, aber es ist nicht dieselbe Person.Sie sind gleich alt, aber nicht die gleiche Person. Eine Zeichenfolge entspricht möglicherweise einer anderen, ist jedoch nicht dasselbe Objekt.
quelle
jack1.age = 99
, ändert sich dies nichtjack2.age
. Das liegt daran, dass es sich also um zwei verschiedene Instanzen handeltjack1 is not jack2
. Sie können sich jedoch gleichen,jack1 == jack2
wenn ihr Name und ihr Alter gleich sind. Für Zeichenfolgen wird es komplizierter, da Zeichenfolgen in Python unveränderlich sind und Python häufig dieselbe Instanz wiederverwendet. Ich mag diese Erklärung, weil sie eher die einfachen Fälle (ein normales Objekt) als die Sonderfälle (Zeichenfolgen) verwendet.Dies ist eine Randnotiz, aber in idiomatischer Python sehen Sie oft Dinge wie:
Dies ist sicher, da garantiert eine Instanz des Null-Objekts vorhanden ist (dh keine) .
quelle
Wenn Sie nicht sicher sind, was Sie tun, verwenden Sie das '=='. Wenn Sie etwas mehr darüber wissen, können Sie 'is' für bekannte Objekte wie 'None' verwenden.
Andernfalls werden Sie sich fragen, warum die Dinge nicht funktionieren und warum dies passiert:
Ich bin mir nicht einmal sicher, ob einige Dinge zwischen verschiedenen Python-Versionen / -Implementierungen garantiert gleich bleiben.
quelle
Aufgrund meiner begrenzten Erfahrung mit Python werden
is
zwei Objekte verglichen, um festzustellen, ob sie dasselbe Objekt sind, im Gegensatz zu zwei verschiedenen Objekten mit demselben Wert.==
wird verwendet, um festzustellen, ob die Werte identisch sind.Hier ist ein gutes Beispiel:
s1
ist eine Unicode-Zeichenfolge unds2
eine normale Zeichenfolge. Sie sind nicht vom selben Typ, aber vom selben Wert.quelle
Ich denke, es hat damit zu tun, dass, wenn der 'is'-Vergleich als falsch ausgewertet wird, zwei unterschiedliche Objekte verwendet werden. Wenn es als wahr ausgewertet wird, bedeutet dies, dass es intern genau dasselbe Objekt verwendet und kein neues erstellt, möglicherweise weil Sie es innerhalb eines Bruchteils von etwa 2 Sekunden erstellt haben und weil zwischen dem optimierten und dem optimierten Objekt keine große Zeitlücke besteht verwendet das gleiche Objekt.
Aus diesem Grunde sollten Sie den Gleichheitsoperator verwenden
==
, nichtis
, um den Wert eines String - Objekt zu vergleichen.In diesem Beispiel habe ich s2 erstellt, ein anderes Zeichenfolgenobjekt, das zuvor gleich "Eins" war, aber nicht dasselbe Objekt wie "
s
, da der Interpreter nicht dasselbe Objekt verwendet hat, wie ich es ursprünglich nicht" Eins "zugewiesen habe. Wenn ich es gehabt hätte, hätte es sie zum gleichen Objekt gemacht.quelle
.replace()
als Beispiel in diesem Zusammenhang ist jedoch wahrscheinlich nicht die beste, da die Semantik verwirrend sein kann.s2 = s2.replace()
erstellt immer ein neues Zeichenfolgenobjekt, weist das neue Zeichenfolgenobjekt zus2
und entsorgt dann das Zeichenfolgenobjekt, auf dass2
früher verwiesen wurde. Selbst wenn Sie dies tuns = s.replace('one', 'one')
würden, würden Sie immer noch ein neues Zeichenfolgenobjekt erhalten.Ich glaube, dass dies als "internierte" Saiten bekannt ist. Python tut dies ebenso wie Java und C und C ++ beim Kompilieren in optimierten Modi.
Wenn Sie zwei identische Zeichenfolgen verwenden, anstatt Speicherplatz durch Erstellen von zwei Zeichenfolgenobjekten zu verschwenden, verweisen alle internierten Zeichenfolgen mit demselben Inhalt auf denselben Speicher.
Dies führt dazu, dass der Python-Operator "is" True zurückgibt, da zwei Zeichenfolgen mit demselben Inhalt auf dasselbe Zeichenfolgenobjekt zeigen. Dies wird auch in Java und in C geschehen.
Dies ist jedoch nur zur Speichereinsparung nützlich. Sie können sich nicht darauf verlassen, um die Zeichenfolgengleichheit zu testen, da die verschiedenen Interpreter und Compiler sowie die JIT-Engines dies nicht immer tun können.
quelle
Ich beantworte die Frage, obwohl die Frage zu alt ist, da keine der obigen Antworten die Sprachreferenz zitiert
Tatsächlich prüft der Operator auf Identität und der Operator auf Gleichheit.
Aus der Sprachreferenz:
Typen beeinflussen fast alle Aspekte des Objektverhaltens. Sogar die Bedeutung der Objektidentität wird in gewissem Sinne beeinflusst: Bei unveränderlichen Typen können Operationen , die neue Werte berechnen, tatsächlich einen Verweis auf ein vorhandenes Objekt mit demselben Typ und Wert zurückgeben, während dies für veränderbare Objekte nicht zulässig ist . ZB nach a = 1; b = 1, a und b können sich je nach Implementierung auf dasselbe Objekt mit dem Wert Eins beziehen oder nicht, jedoch nach c = []; d = [], c und d beziehen sich garantiert auf zwei verschiedene, eindeutige, neu erstellte leere Listen. (Beachten Sie, dass c = d = [] sowohl c als auch d dasselbe Objekt zuweist.)
Aus der obigen Aussage können wir schließen, dass die Zeichenfolgen, die ein unveränderlicher Typ sind, möglicherweise fehlschlagen, wenn sie mit "is" überprüft werden, und erfolgreich sein können, wenn sie mit "is" überprüft werden.
Gleiches gilt für int, tuple, die ebenfalls unveränderliche Typen sind
quelle
Die
==
Äquivalenz des Bedienertestwerts. Deris
Operator testet die Objektidentität, Python testet, ob die beiden wirklich dasselbe Objekt sind (dh an derselben Adresse im Speicher leben).In diesem Beispiel hat Python nur ein Zeichenfolgenobjekt und beide erstellt
a
undb
verweist darauf. Der Grund dafür ist, dass Python einige Zeichenfolgen intern zwischenspeichert und als Optimierung wiederverwendet. Es gibt wirklich nur eine Zeichenfolge 'Banane' im Speicher, die von a und b gemeinsam genutzt wird. Um das normale Verhalten auszulösen, müssen Sie längere Zeichenfolgen verwenden:Wenn Sie zwei Listen erstellen, erhalten Sie zwei Objekte:
In diesem Fall würden wir sagen, dass die beiden Listen äquivalent sind, weil sie dieselben Elemente haben, aber nicht identisch, weil sie nicht dasselbe Objekt sind. Wenn zwei Objekte identisch sind, sind sie auch äquivalent, aber wenn sie äquivalent sind, sind sie nicht unbedingt identisch.
Wenn
a
sich ein Objekt auf ein Objekt bezieht und Sie es zuweisenb = a
, beziehen sich beide Variablen auf dasselbe Objekt:quelle
is
vergleicht den Speicherort. Es wird für den Vergleich auf Objektebene verwendet.==
vergleicht die Variablen im Programm. Es wird zur Überprüfung auf Wertebene verwendet.is
prüft auf Äquivalenz der Adressenebene==
prüft auf Wertäquivalenzquelle
is
ist Identitätstest,==
ist Gleichheitstest (siehe Python-Dokumentation ).In den meisten Fällen, wenn
a is b
, danna == b
. Es gibt jedoch Ausnahmen, zum Beispiel:Sie können also nur
is
für Identitätstests verwenden, niemals für Gleichheitstests.quelle