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 des umgekehrten Arrays a, obwohl noch immer b ausgegeben wird. Der Grund für dieses Verhalten ist, dass a und b als Werte dasselbe Array haben und nicht nur wie vorher Arrays mit denselben Elementen.

Obwohl also im ersten Programm die a und b zugewiesenen Arrays die selben 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 Array-Objekt erzeugt und als Wert den Variablen a und b zugewiesen. Dadurch ändert sich auch der Zustand des in b gespeicherten Arrays, sobald der Zustand des in a gespeicherten Arrays 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