doppelte Verweise/Referenzen auf Instanzvariablen [gelöst]

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Hallo zusammen,

ich stehe vor einem mir (im Moment) unlösbaren Problem, welches ich auf das minimalst mögliche Beispiel reduzieren konnte.

Code: Alles auswählen

>>> class Foo(object):
...     def __init__(self, d={}):
...             self.d = d
...
>>> f1 = Foo()
>>> f2 = Foo()
>>> f1.d['blubb'] = "bar"
>>> f2.d.keys()
['blubb']
>>>
Wie kann ich es verhindern, dass das Dictionary der Instanz f2 nicht mehr eine Referenz auf das Dictionary von f1 verweist, demnach also ein eigenständiges Objekt darstellt?

Soweit ich weiß, fasst der Python-Interpreter (Commandline) String-Literale und sonstige Konstanten zusammen (gleiche Objekt-ID) (wenn sie äquvivalent sind). Mich wundert nur, dass hier eben auch die neuen (leeren) Dictionarys zusammen gefasst werden.

Grüße... Heiko


EDIT:

Lag wohl an der Auswertungsreihefolge für Default-Argumente. Ich hatte das wohl aus dem Hinterkopf verdrängt. Die Instanzierung des Dictionarys habe ich nun in den Konstruktorrumpf verlagert und das Problem ist somit aus der Welt.

Danke für die Aufmerksamkeit... Heiko
epsilon
User
Beiträge: 71
Registriert: Freitag 20. Juni 2008, 19:48

Default-Werte werden während der Definieren einer Funktion an das Objekt der Funktion gebunden und nicht wenn die Funktion aufgerufen wird. Dictionaries sind veränderbare Objekte. Das heißt es wird kein neues Objekt erstellt, wenn man dem dict. etwas hinzufügt (im Gegensatz zu strings, welche unveränderlich sind, wodurch immer ein neues string Objekt erstellt werden muss, wenn du dem string etwas anhängen willst). Im Endeffekt verwenden also alle Objekte das selbe dict. als Default-Wert.

Edit: Was meinst du mit "Auswertungsreihefolge"?
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Edit: Was meinst du mit "Auswertungsreihefolge"?
So ziemlich das selbe, was du soeben beschrieben hast. Mir fiel gerade nur kein besserer Begriff ein.

Grüße... Heiko
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich würde es so machen:

Code: Alles auswählen

def __init__(self, d=None):
    self.d = d or {}
Die Merkregel ist: Benutze niemals veränderliche Objekte in den Parameterlisten von Funktions- und Methodendefinitionen.

Stefan
Antworten