Seite 1 von 1

doppelte Verweise/Referenzen auf Instanzvariablen [gelöst]

Verfasst: Donnerstag 7. August 2008, 12:35
von bwbg
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

Verfasst: Donnerstag 7. August 2008, 12:52
von epsilon
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"?

Verfasst: Donnerstag 7. August 2008, 13:10
von bwbg
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

Verfasst: Sonntag 10. August 2008, 09:24
von sma
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