支持自定义类的深层复制操作?

时间:2014-09-22 15:39:01

标签: python copy

我有一个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 的正确方法吗?

2 个答案:

答案 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__,所以这具有您期望出错的标准行为。