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

我想创建一个类,该类可以提供不会被深度复制的属性列表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__()方法)。有什么办法可以做到吗?


料青山看我应如是
浏览 800回答 2
2回答

弑天下

任何时候你实现一个特殊的方法(如__getattr__,__deepcopy__,__str__,等),您可能需要上浮MRO超或使用原来的某个子集。我尚不清楚您是如何记忆属性的,但我将简化您的示例。假设您始终使用相同的a(并且它是不可变的,不需要复制),但是否则,您想要复制b。(你可以通过a和b直接构造,使一个新的对象。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)

慕码人8056858

copy.deepcopy仅__deepcopy__在存在该方法的情况下才会调用-我们可以通过保存__deepcopy__,调用copy.deepcopy(...)的值,__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
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python