Exkurs: (un-)veränderbare Objekte
Exkurs: (un-)veränderbare Objekte#
In Python gibt es veränderbare und unveränderbare Objekte. Die eine Art von Objekten kann man also verändern, die andere Art von Objekten kann man nicht verändern.
Stell dir vor, du besitzt ein Auto. Um damit ordentlich Eindruck auf der Straße zu machen, möchtest du gerne dein Auto tunen lassen und von 100 PS auf 150 PS upgraden. Du fährst also in eine Werkstatt und bittest um die gewünschte Veränderung. In der Werkstatt könntest du nun zwei Dinge zu hören bekommen, nämlich entweder
“Ja, kein Problem, wir können dein Auto wie gewünscht verändern!”
oder
“Nein, deinen Autotyp kann man leider nicht wie gewünscht verändern. Wir können dir aber anbieten, dein Auto gegen ein anderes mit den gewünschten Eigenschaften einzutauschen!”.
Dein Auto ist also entweder ein veränderbares Objekt oder ein unveränderbares Objekt. Ist dein Auto veränderbar, so kann man es verändern, aber “dein Auto” ist nach der Veränderung immer noch “dein Auto” d.h. dasselbe (aber eben nun veränderte) Objekt. Ist dein Auto hingegen unveränderbar, du möchtest aber trotzdem die Veränderung, so bleibt dir nichts anderes übrig als “dein Auto” durch ein “anderes Auto” auszutauschen. Dadurch wird ein anderes Auto schließlich zu “deinem Auto”. Ein anderes Objekt nimmt dann also den Platz “deines Autos” ein.
Genau so ist das auch in Python. Es gibt Objekte, die kann man verändern, und Objekte, die kann man nicht verändern, sondern nur austauschen, wenn man etwas anderes will. Das ist relevant, wenn man Variablen bzw. die Objekte hinter den Variablen verändern möchten. In Python sind Variablen immer nur Beschriftungen für bzw. Zeiger auf Objekte, nicht aber die Objekte selbst. Das ist so, wie der Begriff “mein Auto” auf ein Auto verweist, aber nicht das Auto selbst ist, sondern nur ein Begriff bzw. Gedanke. Möchte man eine Variable in Python verändern, hängt es vom Objekt-Typ des von der Variable beschrifteten Objektes ab, ob
das Objekt verändert werden kann und die Variable nach der Veränderung immer noch auf dasselbe (aber eben nun veränderte) Objekt zeigt
oder
das Objekt nicht verändert werden kann, ausgetauscht werden muss und die Variable nach der Veränderung auf ein komplett anderes Objekt zeigt
Das ist so, wie im Beispiel oben, wo je nach Auto-Typ entweder das durch “mein Auto” beschriftete Auto verändert werden kann oder man tauscht das gesamte Auto aus, sodass die Beschriftung “mein Auto” einem neuen Objekt zugeordnet wird.
Schauen wir uns das mal konkret in Python an. Die meisten Standard-Objekte in Python sind unveränderbar. Dazu gehören z.B. Objekte vom Typ Integer, Float und String. Wenn wir z.B. das Integer-Objekt 100
einer Variable zuweisen, dann beschriften wir das Objekt 100
mit dem gewählten Variablennamen. Das mache ich beispielsweise hier:
my_integer = 100
Eine Variable ist aber, wie gesagt, wirklich immer nur eine Beschriftung eines Objektes und nicht das Objekt selbst. Daher verändere ich mit folgendem Code auch nicht das Objekt 100
in das Objekt 150
, sondern beschrifte nun das Objekt 150
mit dem Namen my_integer
:
my_integer = my_integer + 50
my_integer
150
Das Objekt 100
wurde also nicht verändert, sondern der Wert des Variablennamen my_variable
überschrieben bzw. dem Variablenname my_variable
wurde ein anderes Objekt zugewiesen.
Woher weiß ich, dass sich hinter der Variable my_integer
nun ein vollkommen neues Objekt verbirgt und nicht dasselbe Objekt in veränderter Form? Das kann man u.a. mit der Funktion id()
sehen. Steckt man ein Objekt in die Funktion id()
, dann bekommt man eine Art Identifikationsnummer heraus über welche man ein Objekt eindeutig identifizieren kann. Gehen wir das obige Beispiel nochmal durch, aber wenden dabei immer wieder die Funktion id()
an, um die wahre Identität der Objekte und Variablen zu enthüllen.
Hier weise ich zunächst die 100
der Variable my_integer
zu:
my_integer = 100
Gucken wir mal, welche Identifikationsnummer uns die Funktion id()
für die Variable my_integer
bzw. für das Objekt, welches wir mit my_integer
benannt haben, herausgibt:
id(my_integer)
140718436266880
Aha. Diese Zahl sagt uns alleine nicht wirklich viel. Interessanterweise ist aber diese Identifikationsnummer nichts anderes als die Identifikationsnummer des Objekts 100
selbst:
id(100)
140718436266880
Das ist logisch, wenn man bedenkt, dass die Variable my_integer
nur eine Beschriftung für das eigentliche Objekt 100
ist. Die Variable my_integer
verweist nur auf das Objekt 100
.
Nun verändere ich die Variable my_integer
, indem ich sie überschreibe:
my_integer = my_integer + 50
Welches Objekt versteckt sich jetzt hinter my_integer
?
id(my_integer)
140718436268480
Jetzt hat sich die Identifikationsnummer verändert. Diese Identifikationsnummer ist nun die Identifikationsummer für das Objekt 150
, auf welches die Variable my_integer
nun verweist.
id(150)
140718436268480
Das ist alles etwas verwirrend. Denn eigentlich fühlt es sich ja so an, dass wir das “Objekt” my_integer
verändern würden, wenn wir dieser Variable einen neuen Wert zuweisen. In Wahrheit ist die Variable my_integer
ja aber nicht das Objekt selbst, sondern nur eine Beschriftung für ein Objekt. Wir ändern somit also die Zuordnung der Beschriftung. Wir tauschen das Objekt 100
gegen das Objekt 150
und beschriften nun eben die 150
mit my_integer
. Das ist so, wie wenn wir bei “mein Auto” anfangen an ein neues Auto zu denken, falls das alte Auto ausgetauscht werden musste, weil es unveränderbar war.
Es gibt jedoch auch Objekte in Python, die können wir tatsächlich verändern. Bei diesen ist es dann so, dass wir wirklich das Objekt hinter dem Variablennamen verändern, sodass der Variablenname immer noch dasselbe, aber eben nun veränderte Objekt beschriftet (“mein Auto” bleibt “mein Auto”, wurde aber verändert). Zu den veränderbaren Objekten, die wir schon kennengelernt haben, gehören in Python z.B. die Listen!
Im Folgenden erstelle ich zunächst eine Liste und lasse mir dann die Identifikationsnummer der Liste ausgeben. Dann verändere ich die Liste und schaue, ob die Identität der Liste gleichgeblieben ist.
# Liste erstellen
my_list = [100, 200, 300]
# Identifikationsnummer ausgeben
id(my_list)
1875432623680
# Liste verändern
my_list.append(400)
# Liste nochmal verändern
my_list[0] = 0
# Liste angucken
my_list
[0, 200, 300, 400]
# Identifikationsnummer angucken
id(my_list)
1875432623680
Wir sehen, die Liste wurde verändert, ist aber nach wie vor dasselbe Objekt mit derselben Identifikationsnummer. Die Variable my_list
verweist also nach wie vor auf dasselbe Objekt. Das Objekt selbst wurde aber verändert.
Uff! Das ist schon echt kompliziert. Nun wissen wir, dass es veränderbare und unveränderbare Objekte in Python gibt. Aber warum ist das wichtig? Ob ein Objekt veränderbar oder unveränderbar ist, macht eben immer dann einen Unterschied, wenn wir ein Objekt bzw. eine Variable verändern wollen. Und im Folgenden schauen wir uns an, wie man innerhalb von For-Loops die Elemente der Liste, auf die man im For-Loop zugreift, verändern kann. Je nachdem, ob die Elemente der Liste veränderbar sind oder nicht, müssen wir einen bestimmten Weg verwenden, um die Elemente in der Liste zu ändern.