首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python:如何为继承了新属性的基类实现复制

Python:如何为继承了新属性的基类实现复制
EN

Stack Overflow用户
提问于 2018-05-28 19:31:55
回答 1查看 689关注 0票数 2

如何为继承了新属性的基类实现复制,而没有为继承的类实现__copy__ (意味着新属性的哑巴复制)?

也就是说,我们的类有一个用户定义的字段和一个计算的(或外部引用,不应复制)字段。因此copy应该创建实例,仅基于用户定义的字段:

class A(object):
    def __init__(self, a):
        self.a = a
        self.b = a+1

    def __copy__(self):
        return A(self.a)

目前,copy运行良好。

然后我们引入了继承类,继承类的构造函数根据自己的参数计算基类的参数,并引入了新的字段,所以继承构造函数的签名对于基类来说是完全不同和未知的(共同的):

class B(A):
    def __init__(self, c):
        A.__init__(self, c+100)
        self.c=c

此时,返回A实例,copy显然不能正常工作。当然,我们可以为继承的类实现自己的__copy__,但是当我们引入一些属性时,这是非常不方便的,这些属性应该以普通的方式复制。所以我想要实现的是,通过A.__copy__复制继承类B的"A部分“,但仍然是通过标准复制,没有为所有继承类重新实现__copy__。那么,对于这种情况,有没有什么“设计模式”呢?

更新:我想将示例从copy重新表述为deepcopy,它更接近真实案例。所以我们的想法是一样的-我们必须管理A类的深度复制,它包含不应该被深度复制的引用(即链接到容器,其中包含对象)。但是我们不想管理继承类的深度复制。

from copy import deepcopy

class A:

    def __init__(self, content, container):
        self.content = content
        self.container = container

    def __deepcopy__(self, memo):
        return A(deepcopy(self.content, memo), self.container)

class B(A):

    def __init__(self, attr):
        A.__init__(self, [1,2,3], self)
        self.attr = attr

b = B(123)
b1=deepcopy(b) # wrong!

看起来我找到了适合我的特定情况的模式(thx @mhawke):首先复制所有内容,然后只深度复制必要的字段。

class A:
    def __deepcopy__(self, memo):
        o = copy(self)
        o.content = deepcopy(self.content)
        return o

但它不能解决常见情况下的问题:对于深度复制,我希望深度复制继承的属性,而不是复制它,并仅在必要时才管理覆盖的深度复制。

EN

回答 1

Stack Overflow用户

发布于 2018-05-28 19:41:35

对于你的例子来说,这是可行的--你“只”需要覆盖_copyattrs -,现在我不确定这是否比仅仅覆盖__copy__更好。

class A(object):
    _copyattrs = ["a"]

    def __copy__(self):
        args = [getattr(self, attrname) for attrname in self._copyattrs]
        return type(self)(*args) 


class B(A):
    _copyattrs = ["c"]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50565444

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档