此示例代码有点奇怪,但请耐心等待......
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': {}}
我本来期望我的{'123' = 'abc'}
已经通过第二次打印,因为字典应该通过引用传递给递归__init__
调用。但是,如果我改变这一行:
self._internal_dict[attribute_name] = {}
到此:
self._internal_dict[attribute_name] = {'test': 1}
然后我得到以下印刷品:
{'test': 1}
{'ay': {'test': 1}, 'ax': {'test': 1, '123': 'abc'}}
为什么启动字典数据会导致它通过引用正确传递?
答案 0 :(得分:6)
这是问题所在:
self._internal_dict = internal_dict or {}
空字典是假的,所以你会在后续的递归调用中得到一个 new 空字典。这就是为什么将dict初始化为非空(truthy)“修复”它的原因。
你想:
self._internal_dict = {} if internal_dict is None else internal_dict
答案 1 :(得分:0)
您班级的问题是您分配self._internal_dict
变量的快捷方式。
不幸的是,空字典的真值为false。
如果您将代码更改为:
,则代码可以正常运行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': {}}