3 回答
TA贡献1783条经验 获得超5个赞
您面临的问题是,您正在尝试构建本机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']))
非常非常奇怪
添加回答
举报
