Seite 1 von 1
Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Sonntag 20. Juni 2010, 11:17
von Dingels
Hi Leute,
ich habe ein Programm geschrieben, in dem sehr viele Strings auf ihren Inhalt hin überprüft werden. Bisher habe ich dafür immer den "=="-Operator verwendet. Ist es schlechter Stil, wenn man stattdessen den "is"-Operator nimmt? In PEP 8 konnte ich dazu nichts finden. Ich kenne den Unterschied zwischen beiden Operatoren und weiß, dass "is" die Identität zweier Objekte vergleicht und "==" nur die Gleichheit der Inhalte der Objekte. Aber da ich nur Strings auf ihre Inhalte hin überprüfe und Strings zu den unveränderlichen Datentypen gehören, würde der "is"-Operator dieselben Ergebnisse liefern. Ich frage das deshalb, weil der "is"-Operator einfach schöner zu lesen ist als "==".
Besten Dank.

Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Sonntag 20. Juni 2010, 11:21
von Rebecca
Code: Alles auswählen
>>> s1 = "hallo welt bla bla bla bla bla!"
>>> s2 = "hallo welt bla bla bla bla bla!"
>>> s1 is s2
False
Auch immutable Objekte koennen den gleichen Inhalt haben und doch verschiedene Objekte sein! Genau genommen optimiert CPython zwar einige Strings und Integer, sodass man hier evtl tatsaechlich Objektidentitaet hat, das ist aber ein Implementierungsdetail, worauf man sich nicht verlassen sollte!
Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Sonntag 20. Juni 2010, 11:27
von Dingels
Hallo Rebecca,
vielen Dank für die prompte Antwort. Tolles Forum hier.

Aber das habe ich tatsächlich noch nicht gewusst. Ich dachte, unveränderliche Datentypen haben immer dieselbe Identität. Das Verhalten find ich irgendwie doof. Aber ok, dann hab ich mit dem "=="-Operator ja alles richtig gemacht.
Danke nochmals und schönen Sonntag noch.

Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Sonntag 20. Juni 2010, 11:31
von ms4py
Noch als Ergänzung: "None" prüft man normalerweise mit `is`
Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Sonntag 20. Juni 2010, 12:04
von Darii
Dingels hat geschrieben:Aber das habe ich tatsächlich noch nicht gewusst. Ich dachte, unveränderliche Datentypen haben immer dieselbe Identität. Das Verhalten find ich irgendwie doof.
Warum sollten sie? Porzellanteller kann man auch nicht verändern (nur kaputt machen), trotzdem sind zwei gleiche Teller nicht dieselben Objekte.
Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Sonntag 20. Juni 2010, 12:06
von Dav1d
Was noch nicht erwähnt wurde:
Code: Alles auswählen
>>> s1 = 'ein string'
>>> s2 = 'ein string'
>>> s3 = s1
>>> s1 is s2
False
>>> s2 is s3
False
>>> s1 is s3
True
Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Sonntag 20. Juni 2010, 12:18
von Barabbas
Dingels hat geschrieben:Aber das habe ich tatsächlich noch nicht gewusst. Ich dachte, unveränderliche Datentypen haben immer dieselbe Identität. Das Verhalten find ich irgendwie doof.
Da bringst du jetzt aber etwas durcheinander: Das Beispiel von Rebecca demonstriert nicht Unveränderlichkeit. Es demonstriert, wie zwei String-Objekte erstellt werden, die die gleiche Zeichenkette beinhalten (bitte korrigiert mich, wenn ich das nicht richtig ausdrücke). Das ist eigentlich immer so. Es gibt sicher auch nur wenig Fälle, in denen du möchtest, dass unabhängig voneinander erstellte Objekte miteinander identisch sind. Das würde in den meisten Fällen sicher zu Fehlern führen, die kaum nachzuvollziehen wären.
Unveränderlichkeit beschreibt nur was passiert, wenn du irgendein Objekt veränderst. Ein unveränderliches Objekt lässt sich nicht verändern, so dass immer ein ganz neues Objekt mit dem neuen Inhalt erstellt werden muss.
@Dav1d:
Naja, das ist ja selbstverständlich. Alles andere fände ich äußerst verwunderlich. Interessanter finde ich da schon dieses Beispiel:
>>> a = 100
>>> b = 100
>>> a is b
True
>>> a = 1000
>>> b = 1000
>>> a is b
False
Sehr verwirrender Effekt, hängt aber (wenn ich das richtig in Erinnerung habe) nur damit zusammen, dass Python Int-Objekte für die Zahlen von 0 - 100 beim Start generiert und bei Bedarf nur noch Verweise auf diese Objekte rausrückt.
Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Sonntag 20. Juni 2010, 12:27
von Leonidas
Noch mehr Spaß mit Objektidentität:
Code: Alles auswählen
>>> a = 42
>>> b = 42
>>> a is b
True
>>> c = 420
>>> d = 420
>>> c is d
False
Bei CPython ist es nämlich so dass die Integer bis 100 gecached werden und wenn man so ein Objekt erstellen will, ein bereits existierendes Integer-Objekt zurückgegeben wird. Ab 100 sieht es dann schon anders aus.
Captain Obvious: Verschiedene Operatoren machen verschiedene Sachen.

Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Sonntag 20. Juni 2010, 13:32
von BlackJack
Und noch ein bisschen Gedankenfutter:
Code: Alles auswählen
In [1493]: a = 'Hallo'
In [1494]: b = 'Hallo'
In [1495]: a is b
Out[1495]: True
In [1496]: a = 'Hallo Welt'
In [1497]: b = 'Hallo Welt'
In [1498]: a is b
Out[1498]: False
In [1499]: a = 'Hallo Welt'; b = 'Hallo Welt'
In [1500]: a is b
Out[1500]: True
Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Sonntag 20. Juni 2010, 14:23
von sma
Mit anderen Worten: `is` sollte man nur benutzen, wenn man Objektidentitäten vergleichen will, ansonsten lieber immer `==`, was Gleichheit prüft. Identische Objekte sind in der Regel (eigentlich fällt mir keine Ausnahme ein) gleich, aber gleiche Objekte müssen nicht identisch sein.
Stefan
Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Sonntag 20. Juni 2010, 15:11
von pillmuncher
@sma:
Code: Alles auswählen
import time
class Foo(object):
def stupid(self):
time.sleep(.05)
return time.time()
def __eq__(self, other):
return self.stupid() == other.stupid()
x = y = Foo()
print x is y
print x == y

Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Sonntag 20. Juni 2010, 15:12
von Darii
sma hat geschrieben:Identische Objekte sind in der Regel (eigentlich fällt mir keine Ausnahme ein) gleich
float-NaNs. NaN ist immer ungleich zu allem.
Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Montag 21. Juni 2010, 13:49
von philistion
Hallo BlackJack, dein Beispiel verwirrt mich jetzt. Könntest du die Effekte bei 1495 und 1500 näher ausführen?
Ist dieses Verhalten gewollt? Wenn ja warum?
Danke!
Re: Welchen Operator soll ich benutzen? "==" oder "is"?
Verfasst: Montag 21. Juni 2010, 14:21
von BlackJack
Da Verhalten ist gewollt, aber eben ein Implementierungsdetail, man darf sich nicht darauf verlassen! Das muss nicht so sein.
Ad 1495: Alles was sich an die Regeln für gültige Bezeichner in Python-Quelltext hält, also zum Beispiel "Hallo" wird intern noch einmal vermerkt und neue literale Zeichenketten werden gegen diese interne Buchführung überprüft und nur einmal angelegt. Ganz einfach weil Attribute auf Objekten ja intern als Dictionaries, die Zeichenketten auf Objekte abbilden, gespeichert werden. Wenn man dafür sorgt, dass Bezeichner möglichst nur einmal im Speicher angelegt werden, spart man Speicherplatz und der Vergleich zwischen solchen Zeichenketten kann schneller implementiert werden weil gleiche `id()` auf jeden Fall auch gleicher Wert bedeuten.
Ad 1500: Bei Eingabe 1499 sieht der Compiler beide Zuweisungen und Literale auf einmal und erkennt, dass die Literale den gleichen Wert haben. CPython schaut also innerhalb einer Übersetzungseinheit, im normalen Betrieb ist das ein Modul, ob Zeichenketten mehrfach vorkommen und legt in dem Fall nur *eine* an. Das kann man bei "immutable" Objekten ja machen ohne die Semantik zu ändern.