is vergleicht die Identität von Objekten (das heißt, zeigen die Variablen auf denselben Speicherbereich).== (Operator eq) vergleicht die Werte, das heißt, sind die Objekte hinsichtlich ihres Inhalts gleich.is sollte verwendet werden, um genau die Identität zu vergleichen (z.B. mit None oder für Singleton-Objekte) und nicht um die Gleichheit der Werte zu überprüfen.
Beispiel:
a = [1, 2, 3] b = [1, 2, 3] print(a == b) # True print(a is b) # False c = None d = None print(c is d) # True
Bei der Arbeit mit kleinen Ganzzahlen oder Strings kann der Interpreter "Internierung" (aufbewahrte Objekte) verwenden, was manchmal is für gleiche Werte wahr macht, dies sollte jedoch nicht in der Logik des Programms verwendet werden.
Frage: Was wird der folgende Code ausgeben?
a = 256 b = 256 print(a is b) c = 257 d = 257 print(c is d)Warum?
Antwort:
Für Werte von -5 bis 256 verwendet Python einen Pool von Ganzzahlen. Werte in diesem Bereich zeigen immer auf dasselbe Objekt, daher ergibt a is b True. 257 liegt bereits außerhalb des Pools, daher wird c is d False ergeben (die Objekte sind unabhängig).
Geschichte
In einem Mikrodienst wurde der Vergleich von Strings mit is anstelle von == durchgeführt. Aufgrund der Optimierungen des Interpreters funktionierte das Programm in Tests "stabil", begann jedoch nach einer Neukompilierung oder anderen Änderungen der Umgebung zu versagen.
Ein Entwickler verwendete den Operator is anstelle von == zum Vergleichen von Zahlen. Dies funktionierte für kleine Zahlen (dank des Pools), führte jedoch bei großen Zahlen zu Ausfällen und unvorhersehbaren Ergebnissen, was die Berechnungslogik beeinträchtigte.
Bei der Planung eines Authentifizierungssystems wurde das empfangene JSON korrekt mit is None überprüft, dann wurde analog auch für Strings so vorgegangen: if status is "ok". Das stellte sich als Fehler heraus – manchmal wurde die Bedingung nicht erfüllt, was zu einer falschen Datenverarbeitung führte.