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': {}} 
  • Den längsten Teilstring in alphabetischer Reihenfolge finden
  • Python - Eigenschaftseinstellung aus der Liste verursacht maximale Rekursionstiefe überschritten
  • Rekursionsfunktion in Python
  • Python Recursive Funktion für Collatz Conjecture
  • Python RuntimeError: maximale Rekursionstiefe überschritten
  • Python-Rekursions-Permutationen
  • Notwendigkeit, Pyramiden-Dreieck auf Python neu zu erstellen
  • Python rekursiv anhängen Liste Funktion
  • Refactoring zur Beseitigung der globalen Variablen in rekursiver Funktion
  • Was ist die maximale Rekursionstiefe in Python und wie man es erhöht?
  • Baktracking-Funktion, die die Berechnung berechnet, überschreitet die maximale Rekursionstiefe
  • Python ist die beste Programmiersprache der Welt.