Ein anderes Duplikat fragte, warum zwei gleiche Zeichenfolgen im Allgemeinen nicht identisch sind, was hier nicht wirklich beantwortet wird:
>>> x = 'a'
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False
Warum sind sie nicht die gleiche Saite? Besonders angesichts dessen:
>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True
Lassen Sie uns den zweiten Teil etwas verschieben. Wie konnte der erste wahr sein?
Der Interpreter müsste über eine "interne Tabelle" verfügen, eine Tabelle, die Zeichenfolgenwerte Zeichenfolgenobjekten zuordnet. Jedes Mal, wenn Sie versuchen, eine neue Zeichenfolge mit dem Inhalt zu erstellen 'abc'
, erhalten Sie dasselbe Objekt zurück. Wikipedia hat eine detailliertere Diskussion darüber, wie Internierung funktioniert.
Und Python hat eine String-Internierungstabelle; Sie können Zeichenfolgen mit der sys.intern
Methode manuell internieren .
In der Tat ist Python erlaubt automatisch intern jede unveränderlichen Typen, aber nicht erforderlich , dies zu tun. Unterschiedliche Implementierungen führen zu unterschiedlichen Werten.
CPython (die Implementierung, die Sie verwenden, wenn Sie nicht wissen, welche Implementierung Sie verwenden) automatisiert automatisch kleine Ganzzahlen und einige spezielle Singletons wie False
, aber keine Zeichenfolgen (oder große Ganzzahlen oder kleine Tupel oder irgendetwas anderes). Sie können dies ziemlich leicht sehen:
>>> a = 0
>>> a += 1
>>> b = 1
>>> a is b
True
>>> a = False
>>> a = not a
>>> b = True
a is b
True
>>> a = 1000
>>> a += 1
>>> b = 1001
>>> a is b
False
OK, aber warum waren z
und w
identisch?
Das ist nicht der Interpreter, der automatisch interniert, sondern die Compiler-Faltwerte.
Wenn das gleiche Kompilierung-String zweimal im selben Modul erscheint (was genau das bedeutet , ist schwer zu definieren-es ist nicht das gleiche wie ein Zeichenfolgenliteral, weil r'abc'
, 'abc'
und 'a' 'b' 'c'
sind alle verschieden Literale aber die gleiche Zeichenfolge, aber leicht zu verstehen intuitiv) erstellt der Compiler nur eine Instanz der Zeichenfolge mit zwei Referenzen.
Der Compiler kann sogar noch weiter gehen: Er 'ab' + 'c'
kann 'abc'
vom Optimierer konvertiert werden. In diesem Fall kann er zusammen mit einer 'abc'
Konstanten im selben Modul gefaltet werden.
Auch dies ist Python erlaubt, muss aber nicht. In diesem Fall faltet CPython jedoch immer kleine Zeichenfolgen (und z. B. auch kleine Tupel). (Obwohl der Statement-by-Statement-Compiler des interaktiven Interpreters nicht die gleiche Optimierung ausführt wie der Compiler für jeweils einzelne Module, werden interaktiv nicht genau die gleichen Ergebnisse angezeigt.)
Was sollten Sie als Programmierer dagegen tun?
Naja nichts. Sie haben fast nie Grund zur Sorge, wenn zwei unveränderliche Werte identisch sind. Wenn Sie wissen möchten, wann Sie a is b
anstelle von verwenden können a == b
, stellen Sie die falsche Frage. Nur immer verwenden, a == b
außer in zwei Fällen:
- Für besser lesbare Vergleiche mit den Singleton-Werten wie
x is None
.
- Bei veränderlichen Werten, wenn Sie wissen müssen, ob sich eine Mutation
x
auf die auswirkt y
.