Hallo Pekh!
Ehrlich gesagt habe ich beim Verfolgen des Threads im Nachhinein sehnsüchtig auf einen erlösenden Post wie den von Numerix gewartet, dank dafür.
Ich würde Numerix Erläuterung gern noch etwas ausführen:
Pekh hat geschrieben:Kann mir das jemand mal bitte erklären? Wenn ich statt des Dicts z.B. einen Integer hinterlege, funktioniert es.
Code: Alles auswählen
In [13]: class T(object):
....: objects = {}
....:
....: def t(self):
....: return T.objects
....:
....:
In [14]: t = T()
In [15]: t.objects={"A":3}
In [16]: t.t()
Out[16]: {}
In [17]: t.objects
Out[17]: {'A': 3}
Mit "t = T()" in Z. 9 erzeugst Du eine neue Instanz der Klasse T, die einen eigenen Namensraum besitzt. Durch Zuweisungen kannst Du Objekte an neue oder bereits existierende Namen binden:
Code: Alles auswählen
t.objects = {"A":3} # bindet das dict an den Namen 'objects' der Instanz
T.objects = {"A":3} # bindet das dict an den Namen 'objects' der Klasse
Man kann von außerhalb und innerhalb auf die Klassenattribute zugreifen, selbst auf die Privaten. Das ist also keineswegs ein workaround oder Trick, sondern grundlegendes Prinzip.
Häufig auftretender Grund für Verwirrung ist auch der Unterschied zwischen Objektänderung und Neubindung.
Wenn Du vor Zeile 11 das Attribut objects von t referenzierst, dann Prüft die Instanz t als erstes, ob der Name im builtin-Attribut __dict__ existiert, sonst delegiert sie die Anfrage an die Klasse weiter, die es dann findet.
Aber sobald Du in Zeile 11 den Namen objects der Instanz t neu bindest, wird der neue Name im __dict__ von t gespeichert und Du greifst bei der nächsten Referenzierung auf das neue Objekt zu, von dem die Klasse T natürlich nichts weiß.
Kleiner Test: ändere das Attribut objects doch mal, anstatt es neu zu binden, etwa so:
Grüße,
Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...