在Python中,我如何调用复制.deepcopydeepMy()的实现\uuMy?

2024-09-30 22:11:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个类,它可以提供一个属性列表,这些属性不是由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)

问题是我认为我不能从__deepcopy__()内调用copy.deepcopy(),因为这会导致无限递归(因为copy.deepcopy()首先检查我的对象是否有__deepcopy__()方法)。我有办法吗?在


Tags: selfnone列表return属性defnotval
2条回答

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

class CustomDeepcopy(object):

    a = SomeSimpleObject()
    b = SomeBigObject()

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

    def __deepcopy__(self,memo):
        for attr in self.dont_deepcopy():
            val = getattr(self,attr,None)
            if val is not None:
                 memo[id(val)]=val
        deepcopy_method = self.__deepcopy__
        self.__deepcopy__ = None
        result = copy.deepcopy(self,memo)
        self.__deepcopy__ = deepcopy_method
        return result

任何时候你实现一个特殊的方法(比如__getattr____deepcopy____str__,等等),你要么需要使用super,要么使用原始方法的某个子集。在

我不太清楚你是如何记忆属性的,但我会简化你的例子。假设您总是使用相同的a(并且它是不可变的,不需要被复制),但是否则,您想要复制b(并且您可以直接将a和{}传递给构造函数来生成一个新对象。在

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)

相关问题 更多 >