Python / Objekte und Variablen
Ein Python-Objekt repräsentiert Daten mit einem Wert und möglichen Operationen; eine Variable ist ein daran gebundener Name. x = 100 bindet x an ein Ganzzahlobjekt. Eine neue Zuweisung ändert, worauf x verweist. Zuweisungen kopieren Objekte nicht automatisch, deshalb können mehrere Namen dieselbe Liste verwenden.
Namen, Objekte und Typen
Im Python-Datenmodell besitzen Objekte Identität, Typ und Wert. Der Typ bestimmt ihre Operationen und Eigenschaften. Die Identität bleibt während der Lebenszeit bestehen; die Änderbarkeit des Werts hängt vom Typ ab. Eine Variable als dauerhaft typisierten Speicherbehälter zu betrachten, erklärt neue Bindungen und gemeinsame Referenzen nur unzureichend.
Die Beispiele benötigen Python 3 und die Standardbibliothek. Ihre Ausgaben wurden mit Python 3.12.14 geprüft. Speichern Sie den vollständigen Code als UTF-8 in objects_demo.py und starten Sie python objects_demo.py im Terminal, gegebenenfalls mit python3. Ersetzen Sie den Inhalt für jedes unabhängige Beispiel.
value = 100
print(value, type(value).__name__)
value = "hello"
print(value, type(value).__name__)
100 int
hello str
value verweist zunächst auf ein int-, danach auf ein str-Objekt. Die Ganzzahl 100 selbst ändert ihren Typ nicht. Eine Zuweisung wertet die rechte Seite aus und bindet das Ergebnis an den linken Namen. type(value) zeigt den Typ des aktuell referenzierten Objekts.
Gemeinsame Liste oder neue Bindung?
second = first erstellt keine Liste als Kopie, sondern lässt beide Namen auf dieselbe Liste verweisen. Vergleichen Sie die Änderung dieses Objekts mit der Neubindung eines Namens:
first = [1, 2]
second = first
second.append(3)
print(first)
print(second)
print(first is second)
first = [0]
print(first)
print(second)
print(first is second)
[1, 2, 3]
[1, 2, 3]
True
[0]
[1, 2, 3]
False
append ändert die gemeinsame Liste; deshalb erscheint die 3 auch über first. first = [0] bindet dagegen nur first an eine neue Liste. second bleibt mit der bisherigen Liste verbunden. Unterscheiden Sie also die Bindung des Namens vom Inhalt des Objekts.
| Operation | Bedeutung | Auswirkung auf den anderen Namen |
|---|---|---|
second = first |
Zusätzlicher Name für dasselbe Objekt | Beide sehen spätere Änderungen |
second.append(3) |
Listenobjekt verändern | Dasselbe Objekt zeigt geänderten Inhalt |
first = [0] |
first an anderes Objekt binden | second behält seine Bindung |
Unveränderliche Objekte und +=
Ganzzahlen, Zeichenketten und Tupel sind unveränderlich (immutable), Listen und Dictionaries veränderlich (mutable). Unveränderlich betrifft das Objekt selbst und verhindert keine neue Zuweisung an seinen Namen.
first = 10
second = first
first += 1
print(first)
print(second)
11
10
Die Ganzzahl 10 wird nicht in 11 umgeschrieben. first wird an das Additionsergebnis gebunden, second verweist weiter auf 10. Bei Listen kann dieselbe Syntax += das vorhandene Objekt verändern. Verallgemeinern Sie das Verhalten deshalb nicht auf alle Typen. Die Elementreferenzen eines Tupels lassen sich nicht ersetzen; eine darin enthaltene Liste kann ihren Inhalt dennoch ändern.
Die passende Kopiertiefe wählen
copy() einer Liste erzeugt eine neue äußere Liste als flache Kopie. Verschachtelte Objekte bleiben gemeinsam. Vergleichen Sie das mit copy.deepcopy() auf denselben Ausgangsdaten:
from copy import deepcopy
original = [[1], [2]]
shallow = original.copy()
deep = deepcopy(original)
shallow[0].append(9)
shallow.append([3])
print(original)
print(shallow)
print(deep)
print(original is shallow)
print(original[0] is shallow[0])
[[1, 9], [2]]
[[1, 9], [2], [3]]
[[1], [2]]
False
True
Die 9 in der inneren Liste von shallow erscheint auch in original. Das zusätzliche [3] in der äußeren Liste von shallow vergrößert original dagegen nicht. deep erhält eine unabhängige Kopie der anfänglichen verschachtelten Daten. Entscheiden Sie zuerst, welche gemeinsame Nutzung beabsichtigt ist. Tiefe Kopien verursachen Aufwand und duplizieren Ressourcen wie Dateien oder Sockets nicht einfach wie gewöhnliche Daten.
== prüft Gleichheit, is Identität
Bei eingebauten Listen vergleicht == Inhalte und is, ob es genau dasselbe Objekt ist. Diese Listen sind getrennt erzeugt, obwohl ihr Inhalt gleich ist:
left = [1, 2]
right = [1, 2]
alias = left
print(left == right)
print(left is right)
print(left is alias)
print(id(left) == id(alias))
missing = None
print(missing is None)
True
False
True
True
True
Verwenden Sie Vergleichsoperatoren ihrem Zweck entsprechend. id() liefert eine Identitätszahl; deren konkreter Wert kann sich je Lauf ändern und ist nicht in jeder Python-Implementierung eine Speicheradresse. Vergleichen Sie Zahlen- und Zeichenkettenwerte nicht mit is aufgrund möglicher Wiederverwendung. Verwenden Sie dafür == und zur Prüfung auf None is None.
del entfernt eine Namensbindung
del ist eine Anweisung, keine Funktion. del first entfernt die Bindung dieses Namens. Solange ein anderer Name auf das Objekt verweist, kann es darüber weiterhin benutzt werden:
first = [1, 2]
second = first
del first
print(second)
try:
print(first)
except NameError:
print("first: NameError")
try:
del unknown_name
except NameError:
print("unknown_name: NameError")
[1, 2]
first: NameError
unknown_name: NameError
second gibt die Liste weiter aus, während der Zugriff auf first NameError auslöst. Auch das Löschen eines unbekannten Namens erzeugt NameError. Die del-Anweisung kann je nach Ziel auch Elemente oder Attribute löschen. Das Entfernen eines Namens garantiert keine sofortige Objektzerstörung oder Speicherfreigabe. Schließen Sie Dateien mit with oder close statt über del.
Gültige und verständliche Namen
Bei einfachen lateinischen Namen beginnt ein Bezeichner mit einem Buchstaben oder Unterstrich; Ziffern sind danach erlaubt. Leerzeichen und Bindestriche sind unzulässig, Groß- und Kleinschreibung unterscheiden sich. Python unterstützt außerdem bestimmte Unicode-Zeichen und beschränkt Namen nicht auf englische Buchstaben.
import keyword
for name in ["user_name", "2name", "class", "first-name", "café", "match"]:
valid = name.isidentifier() and not keyword.iskeyword(name)
print(name, valid)
print("match soft keyword:", keyword.issoftkeyword("match"))
user_name True
2name False
class False
first-name False
café True
match True
match soft keyword: True
isidentifier() akzeptiert die Form von class, deshalb ist zusätzlich keyword.iskeyword() nötig. match ist hier ein kontextabhängiges weiches Schlüsselwort, kein allgemein reserviertes Wort. Beachten Sie die Bezeichner- und Schlüsselwortgrammatik. Schlüsselwortlisten können sich mit der Version ändern; verwenden Sie das keyword-Modul Ihres Interpreters.
Auch gültige Namen wie list oder str können eingebaute Funktionen verdecken. Wählen Sie aussagekräftige Namen wie user_name oder item_count. Prüfen Sie bei NameError Schreibweise, vorherige Zuweisung und den Gültigkeitsbereich des Namens.




