我有一个dict
子类,它添加了新的方法和功能。我想要支持的主要内容是递归更新,它通过逐个更新每个嵌套dict
来实现,而不像{{1}方法。
我使用dict.update
函数就像任何其他对象一样,问题是当我向此类添加属性访问时它无效:
copy.deepcopy
现在我收到了这个错误:
__getattr__ = dict.__getitem__
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
KeyError: '__deepcopy__'
函数正在尝试对此对象使用copy.deepcopy
方法:
__deepcopy__
为什么在添加copier = getattr(x, "__deepcopy__", None)
后发生这种情况?有没有办法解决它而不实现__getattr__
方法?
我从未使用__deepcopy__
方法,因此我尝试添加一个,这就是我所拥有的:
__deepcopy__
这是实施def __deepcopy__(self, memo):
# create a new instance of this object
new_object = type(self)()
# iterate over the items of this object and copy each one
for key, value in self.iteritems():
new_object[key] = copy.deepcopy(value, memo)
return new_object
的正确方法吗?
答案 0 :(得分:2)
您无需在此处实施__deepcopy__
。
问题是,您的__getattr__
始终会调用__getitem__
,这会为不存在的属性引发KeyError
。但在这种情况下,__getattr__
预计会提高AttributeError
。
getattr
的实施捕获AttributeError
,但不捕获KeyError
,因此未处理异常。
在这种情况下,您应该更改__getattr__
以正确提升AttributeError
。
答案 1 :(得分:1)
为了不重复间谍,谁似乎忍者都是我们所有人,这是一个很好的方式来实现你想要的相对安全:
class AttributeDict(dict):
def __init__(self):
self.__dict__ = self
ad = AttributeDict()
ad["a"] = 1
ad.a
#>>> 1
import copy
copy.deepcopy(ad)
#>>> {'a': 1}
由于类只是很简单的字典,这实际上是在CPython上执行此操作的最快方法之一。因为它不会超载__getattr__
,所以这具有您期望出错的标准行为。