Exkurs - Objekte in Python
Datenobjekte in Python
Jedes Datenobjekt in Python hat eine Identitätsnummer, einen Typ und einen Zustand.
Ein Objekt der Klasse Konto
könnte etwa wie folgt beschrieben werden:
Die Identitätsnummer ist die Adresse des Objekts im Speicher. Sie ist eine Zahl, mit der man ein Datenobjekt eindeutig identifizieren kann.
Der folgende Python-Dialog zeigt, wie man Zustand, Identitätsnummer und Typ eines Objekts bestimmt.
>>> k = Konto(3)
>>> k.nr
3
>>> k.stand
0.0
>>> id(k)
20366320
>>> type(k)
<class '__main__.konto'="">
</class>
Veränderbare und unveränderbare Objekte
In Python werden sämtliche Daten durch Objekte repräsentiert.
Python unterscheidet zwischen veränderbaren und unveränderbaren Objekten.
Ein Objekt zur Darstellung einer Zahl wie z.B. der Zahl 0.0 ist ein unveränderbares Objekt.
Sein Wert bzw. Zustand kann nicht verändert werden.
Anders verhält es sich bei veränderbaren Objekten wie z.B. Objekten der Klasse Konto
oder Objekten der Klasse list
. Mit Hilfe geeigneter Operationen lässt sich der Zustand
solcher Objekte verändern.
Dieser Umstand führt dazu, dass sich die beiden folgenden Programme unterschiedlich verhalten. Während die Prozedur in Programm 1 einen Seiteneffekt bewirkt, verändert die Prozedur in Programm 2 den Wert der global definierten Variablen nicht.
Programm 1: Verarbeitung von Objekten
from konto import *
def null(konto):
print(id(konto))
konto.stand = 0.0
print(id(konto))
k = Konto(9)
k.einzahlen(100.0)
print(k.stand)
print(id(k))
null(k)
print(k.stand)
print(id(k))
Programm 2: Verarbeitung von Zahlen
def null(zahl):
print(id(zahl))
zahl = 0.0
print(id(zahl))
z = 100.0
print(z)
print(id(z))
null(z)
print(z)
print(id(z))
Zur Erklärung soll die Abarbeitung mit Hilfe von Objektdiagrammen verdeutlicht werden.
Veränderbare Objekte
Das folgende Ablaufprotokoll verdeutlicht, wie Seiteneffekte bei der Verarbeitung veränderbarer Objekte zustande kommen können.
def null(konto):
konto.stand = 0.0
Zunächst wird ein Objekt der Klasse Konto
erzeugt. Zusätzlich wird die Methode einzahlen
aktiviert.
k = Konto(9)
k.einzahlen(100.0)
Anschließend wird die Variable zur
Verwaltung dieses Objekts als aktueller Parameter der Prozedur null
übergeben.
null(k)
Bei der Parameterübergabe wird die Zuweisung konto = k
ausgeführt. Die lokal verfügbare
Variable konto
verwaltet dann dasselbe Objekt wie die Variable k
.
konto.stand = 0.0
Wenn die Prozedur null
abgearbeitet ist, werden sämtliche nur lokal verfügbaren
Variablen (hier also konto
) wieder entfernt.
Die Objektdiagramme zeigen, dass innerhalb der Prozedur das global definierte Objekt verändert wird. Dies führt also zu einem Seiteneffekt.
Unveränderbare Objekte
Das folgende Ablaufprotokoll verdeutlicht, dass bei der Verarbeitung von Prozeduren / Funktionen bei unveränderbaren Objekten keine Seiteneffekte entstehen.
def null(zahl):
zahl = 0.0
Zunächst wird ein float
-Objekt mit dem Wert 100.0
erzeugt und
mit der Variablen z
verwaltet.
z = 100.0
Diese Variable wird als aktueller Parameter der Prozedur null
übergeben.
null(z)
Bei der Parameterübergabe wird die Zuweisung zahl = z
ausgeführt. Die lokal verfügbare
Variable zahl
verwaltet dann dasselbe Objekt wie die Variable z
.
zahl = 0.0
Da das float
-Objekt mit dem Wert 100.0 unveränderbar ist, führt
die Zuweisung zahl = 0.0
dazu, dass der Variablen zahl
ein anderes
Objekt (ein float
-Objekt mit dem Wert 0.0) zugeordnet wird.
Die lokale Variable zahl
verwaltet nach Abarbeitung der Zuweisung zahl = 0.0
also
ein anderes Objekt als die globale Variable z
.
Nach Abarbeitung der Anweisungen der Prozedur null
werden sämtliche lokal verfügbaren
Variablen (hier also zahl
) wieder entfernt.
Die Objektdiagramme zeigen, dass hier kein Seiteneffekt zustande kommt.