Python leer dict nicht durch Verweis übergeben?

Dieses Beispiel ist Code ist ein bisschen seltsam, aber Bär mit mir …

class Foo(object): def __init__(self, internal_dict = None): self._internal_dict = internal_dict or {} for attribute_name in self.__class__.__dict__.keys(): attr = getattr(self.__class__, attribute_name) if isinstance(attr, str) and attribute_name.startswith("a"): # We are iterating over all string attributes of this class whos name begins with "a" self._internal_dict[attribute_name] = {} setattr(self, attribute_name + '_nested_object', Foo(internal_dict=self._internal_dict[attribute_name])) class FooChild(Foo): ax = "5" ay = "10" fc = FooChild() print fc.ax_nested_object._internal_dict # This prints {} fc.ax_nested_object._internal_dict['123'] = 'abc' print fc._internal_dict # This prints {'ay': {}, 'ax': {}} 

Ich hätte erwartet, dass mein {'123' = 'abc'} zum zweiten Druck gelangt ist, weil das Wörterbuch in den rekursiven __init__ Aufruf per Referenz übergeben werden sollte. Allerdings, wenn ich diese Zeile ändern:

 self._internal_dict[attribute_name] = {} 

Dazu:

 self._internal_dict[attribute_name] = {'test': 1} 

Dann bekomme ich folgendes gedruckt:

 {'test': 1} {'ay': {'test': 1}, 'ax': {'test': 1, '123': 'abc'}} 

Warum ist das Priming, dass Wörterbuch Daten bewirken, dass es ordnungsgemäß durch Verweis übergeben werden?

2 Solutions collect form web for “Python leer dict nicht durch Verweis übergeben?”

Das ist das Problem:

 self._internal_dict = internal_dict or {} 

Ein leerer Dict ist falsy, also bekommst du einen neuen leeren Dict bei nachfolgenden rekursiven Anrufen. Das ist der Grund, warum die Initialisierung der Dict auf nicht-leere (Wahrheit) "behebt" es.

Sie wollen:

 self._internal_dict = {} if internal_dict is None else internal_dict 

Das Problem mit deiner Klasse ist die Verknüpfung, die du self._internal_dict , um die Variable self._internal_dict zuzuweisen.

Leider hat für dich ein leeres Wörterbuch einen Wahrheitswert von falsch.

Ihr Code funktioniert, wenn Sie Ihren Code ändern zu:

 class Foo(object): def __init__(self, internal_dict = None): if internal_dict is None: internal_dict = {} self._internal_dict = internal_dict for attribute_name in self.__class__.__dict__.keys(): attr = getattr(self.__class__, attribute_name) if isinstance(attr, str) and attribute_name.startswith("a"): # We are iterating over all string attributes of this class whos name begins with "a" self._internal_dict[attribute_name] = {} setattr(self, attribute_name + '_nested_object', Foo(internal_dict=self._internal_dict[attribute_name])) class FooChild(Foo): ax = "5" ay = "10" fc = FooChild() print fc.ax_nested_object._internal_dict # This prints {} fc.ax_nested_object._internal_dict['123'] = 'abc' print fc._internal_dict # This prints {'ay': {}, 'ax': {}} 
  • Refactoring zur Beseitigung der globalen Variablen in rekursiver Funktion
  • Python - Eigenschaftseinstellung aus der Liste verursacht maximale Rekursionstiefe überschritten
  • Rekursiv dekrementieren eine Liste durch 1
  • Ich versuche, eine Funktion zu machen, die max aus verschachtelter Liste zurückgibt?
  • Wie man sogar und ungerade Zahlen eines Arrays mit Rekursion summiert
  • Python-Rekursions-Permutationen
  • Python max Rekursion, Frage über sys.setrecursionlimit ()
  • Berechnungsdeterminante einer Matrix (nxn) rekursiv
  • Gibt es eine Möglichkeit, eine rekursive Funktion zu schreiben, die alle ganzen Zahlen in einer Liste durchsucht und sieht, ob irgendwelche zwei gleich einer negativen Summe sind?
  • Rekursionsfunktion funktioniert nicht richtig
  • Python: Rekursive Funktion, um die größte Zahl in der Liste zu finden
  • Python ist die beste Programmiersprache der Welt.