链接 __getitem__ (d['a']['b']) 不适用于自定义字典包装器
Chaining __getitem__ (d['a']['b']) not working with custom dict wrapper
我有一本字典,其中每个键总是以特定字符串作为前缀。该字典可能如下所示:
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. Instead use 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'
我有一本字典,其中每个键总是以特定字符串作为前缀。该字典可能如下所示:
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. Instead use 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'