为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

料青山看我应如是 2021-03-30 08:47:54
我想创建一个类,该类可以提供不会被深度复制的属性列表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__()方法)。有什么办法可以做到吗?
查看完整描述

2 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

任何时候你实现一个特殊的方法(如__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)


查看完整回答
反对 回复 2021-04-05
?
慕码人8056858

TA贡献1803条经验 获得超6个赞

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


查看完整回答
反对 回复 2021-04-05
  • 2 回答
  • 0 关注
  • 799 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号