Python:如何实现基类的副本,该副本适用于继承新属性

时间:2018-05-28 11:31:55

标签: python design-patterns

如何实现基类的副本,该基类适用于继承新属性而没有为继承类实现__copy__(暗示新属性的哑副本)?

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

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

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

此时copy工作正常。

然后我们引入继承类,它的构造函数根据它自己的args计算基础构造函数的args,并引入新的字段,因此继承的构造函数的签名是完全不同的和未知的(共同的) )对于基类:

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

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

UPD: 我想重新拟定从copydeepcopy的示例,这更接近真实案例。所以这个想法是一样的 - 我们必须管理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

但它并不能解决常见问题:对于深度复制我喜欢深度复制继承的属性,而不是复制它,并且只在必要时管理覆盖的深层次。

1 个答案:

答案 0 :(得分:0)

对于您的示例,这可行 - 您“只”必须覆盖_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"]