如何解决链接 __getitem__ (d['a']['b']) 不适用于自定义 dict 包装器
我有一本字典,其中每个键总是以特定字符串开头。 dict 可以是这样的:
d = {
"aa123":{
"aa456": "456","aa789": "789"
}
}
所以我正在编写一个包装器,我可以在不使用前置字符串的情况下查询字典。例如:
print(d["123"]["456"]) # --> should print "456"
这是我的包装器:
class CustDict(dict):
def __init__(self,*args,**kwargs):
self.ns = kwargs.pop("namespace")
super().__init__(*args,**kwargs)
def __getitem__(self,key):
key = f"{self.ns}{key}"
return super().__getitem__(key)
当我使用它时,我收到以下错误:
cust_d = CustDict(d,namespace="aa")
print(cust_d["123"]["456"])
我收到错误:
KeyError: '456'
现在,我知道这是因为 __getitem__
返回的是 dict
而不是 CustDict
的实例。
但是,如果我将 return super().__getitem__(key)
替换为 return CustDict(k,namespace=self.ns)
,则会出现其他错误,例如 ValueError: dictionary update sequence element #0 has length 1; 2 is required
对此的任何解决方案将不胜感激。
解决方法
首先,既然您想覆盖 __getitem__
的实例方法,那么您不应该从 dict
继承子类。如果您从 dict
继承,那么它甚至不会查看 __getitem__
的实例方法。您可以了解更多关于 here 的信息。而是使用 UserDict。
对您的代码稍作修改,然后使其如下所示:
from collections import UserDict
class CustDict(UserDict):
def __init__(self,*args,**kwargs):
self.ns = kwargs.pop("namespace")
super().__init__(*args,**kwargs)
def __getitem__(self,key):
key = f"{self.ns}{key}"
val = super().__getitem__(key)
if isinstance(val,dict):
return CustDict(val,namespace=self.ns)
else:
return val
cust_d = CustDict(d,namespace="aa")
cust_d["123"]
>> {'aa456': '456','aa789': '789'}
cust_d["123"]["456"]
>> '456'
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。