Objekt-Identität

Wir wollen in diesem Kapitel das Verhalten von Programmen mit Mutationen genauer verstehen lernen. Dazu betrachten wir zunächst das folgende Programm:

a = [1,2,3]
b = [1,2,3]
reverse(a)
print(b)

Die Ausgabe dieses Programms ist (wie zu erwarten ist) [1,2,3], da zwar die Reihenfolge der Elemente von a umgekehrt, dann aber der Wert von b ausgegeben wird, der nicht verändert wurde.

Durch eine kleine Änderung ändert sich die Ausgabe dieses Programms:

a = [1,2,3]
b = a
reverse(a)
print(b)

In der zweiten Zeile wird jetzt der Variablen b der Wert von a zugewiesen; die anderen Zeilen bleiben unverändert. Durch diese Änderung gibt das Programm nicht mehr [1,2,3] aus sondern [3,2,1], also den Wert der umgekehrten Liste a, obwohl noch immer b ausgegeben wird. Der Grund für dieses Verhalten ist, dass a und b als Werte dieselbe Liste haben und nicht nur wie vorher Listen mit denselben Elementen.

Obwohl also im ersten Programm die a und b zugewiesenen Listen die gleichen Elemente enthalten, handelt es sich bei ihnen um unterschiedliche Objekte mit unterschiedlichen Identitäten. Die Veränderung des Zustands des einen Objektes hat keinen Einfluss auf den Zustand des anderen.

Im zweiten Programm hingegen wird nur ein list-Objekt erzeugt und als Wert den Variablen a und b zugewiesen. Dadurch ändert sich auch der Zustand der in b gespeicherten Liste, sobald der Zustand der in a gespeicherten Liste geändert wird, da es sich dabei um dasselbe Objekt handelt.

Um diesen Effekt besser zu verstehen, können wir Objekte als Kästen zeichnen, in die wir ihren Zustand schreiben und Variablen als Referenzen auf Objekte, die auf entsprechende Kästen zeigen. Für das erste Programm ergeben sich dabei zwei Kästen mit gleichem Zustand, auf die jeweils eine Variable zeigt. Im zweiten Programm ergibt sich nur ein Kasten, auf den zwei Variablen zeigen.

Der Unterschied zwischen identischen Objekten und solchen, deren Zustände lediglich den gleichen Wert haben, kann in Python durch unterschiedliche Vergleichsfunktionen beobachtet werden. Der Vergleichsoperator == vergleicht die Werte von Objekten während das Schlüsselwort is deren Identität vergleicht. Die folgenden Aufrufe demonstrieren diesen Unterschied:

>>> a = [1,2,3]
>>> b = [1,2,3]
>>> c = a
>>> a == b
True
>>> b == c
True
>>> a == c
True
>>> a is b
False
>>> b is c
False
>>> a is c
True