在Python中,如何在__deepcopy __()的实现中调用copy.deepcopy?

时间:2013-06-24 03:53:09

标签: python copy deep-copy

我想创建一个类,它可以提供copy.deepcopy()未深入复制的属性列表。例如:

class CustomDeepcopy(object):

    a = SomeSimpleObject()
    b = SomeBigObject()

    def dont_deepcopy(self):
        return ['b']

    def __deepcopy__(self,memo):
        #Somehow call copy.deepcopy(self) and have it  
        #deepcopy self.a but not self.b
        #
        #For example, this *almost* works, 
        for attr in self.dont_deepcopy():
            val = getattr(self,attr,None)
            if val is not None:
                 memo[id(val)]=val
        return copy.deepcopy(self,memo)

问题在于我认为我不能在copy.deepcopy()内调用__deepcopy__(),因为这会导致无限递归(因为copy.deepcopy()首先检查我的对象是否有__deepcopy__() 1}}方法)。有什么方法可以做到这一点吗?

2 个答案:

答案 0 :(得分:1)

每次实施特殊方法(例如__getattr____deepcopy____str__等)时,您需要使用super上传mro或使用原始子集

我不完全清楚你是如何记忆属性的,但我会简化你的例子。假设你总是使用相同的a(并且它是不可变的并且不需要复制),但是否则,你想要复制b。 (并且您可以将ab直接传递给构造函数以创建新对象。

class CustomDeepcopy(object):
    def __init__(self, a=None, b=None):
        if a:
            self.a = a
        if b:
            self.b = b

    a = SomeSimpleObject()
    b = SomeBigObject()

    @property
    def dont_deepcopy(self):
        return ['b']
    @property
    def deepcopy_attributes(self):
        return ['a']

    def __deepcopy__(self,memo):
        new_kwargs = dict((k, getattr(self, attr, None)) for attr in self.dont_deepcopy)
        for attr in self.deepcopy_attributes:
            new_kwargs[attr] = copy.deepcopy(getattr(self, attr, None))
        return self.__class__(**new_kwargs)

答案 1 :(得分:0)

如果方法存在,

copy.deepcopy只会调用__deepcopy__ - 我们可以通过保存__deepcopy__的值,调用copy.deepcopy(...),然后恢复{的值来避免这种情况在返回结果之前{1}}:

__deepcopy__