3 回答

TA贡献1783条经验 获得超4个赞
您面临的问题是,您正在尝试构建本机dict
- 对于此类,__getitem__
这只是可以检索其值的几种方法之一。由于字典在 Python 中的实现方式,出于历史和性能原因,有很多方法可以完全绕过__getitem__
,因此,嵌套字典永远不会“包装”在 DotDict 中。(例如:.values()
, items()
, 和 starmap 甚至可能会绕过这些)
您真正想要的是将collections.abc.MutableMapping子类化- 它的构造方式可确保任何项目检索都将通过__getitem__
,(不过,您必须实现文档中指出的方法,包括__delitem__
,__setitem__
和__iter__
- 推荐是将实际数据保留为方法中.data
创建的属性中的普通字典__init__
)。
意识到这也使您可以更好地控制数据,例如,使您能够将数据直接包装在 setitem 上的自定义类中,并且不关心属性检索 - 或者,相反,存储任何映射作为普通字典以节省内存和提高效率,并将其包装在检索中。

TA贡献1829条经验 获得超6个赞
在test_star_star_mapping_maintains_child_dot_dicts您创建一个dict不是DotDict这样的,重构为:
def test_star_star_mapping_maintains_child_dot_dicts(self, dot_dict):
obtained_via_star = DotDict(dict(**dot_dict))
b_dict = obtained_via_star["b"]
assert b_dict.c == 2
将使测试通过,因为您现在正在创建DotDict. 也许您想删除该部分,dict(**dot_dict)以便此版本也可以使用:
def test_star_star_mapping_maintains_child_dot_dicts(self, dot_dict):
obtained_via_star = DotDict(**dot_dict)
b_dict = obtained_via_star["b"]
assert b_dict.c == 2

TA贡献1799条经验 获得超8个赞
哇,尝试使用未注释的方式运行以下代码 __iter__
class DotDict(dict):
# def __iter__(self):
# return super().__iter__()
def __getattr__(self, item):
return self.__getitem__(item)
def __getitem__(self, item):
item = super().__getitem__(item)
if isinstance(item, dict):
return self.__class__(item)
return item
d = DotDict({'a': {'b':'c'}})
print(type(dict(**d)['a']))
非常非常奇怪
添加回答
举报