继承:返回其自身实例的基类方法

时间:2014-03-18 23:27:33

标签: python class inheritance instance subclass

我的基类有一个返回自身实例的方法。当我编写我的子类时,有没有办法让这个实例成为我的子类而不是基类的实例,而不修改基类的代码或将整个基类方法重写到我的子类方法中?

示例:

class A:
    def __init__(self,x):
        self.x = x
    def add(self):
        self.x += 2
    def new(self,z):
        n = A(z)
        return n

class B(A):
    def __init__self():
        A.__init__(self,x)

如果我这样做:

a = B(10)
b = a.new(4)

然后b将是A的实例而不是B的实例,就像我想要的那样。 在这个简单的例子中,我可以覆盖B类中的方法,但在我的程序中我不想,它只会破坏可移植性,因为我无法控制基类,因为它是另一个包的一部分。 / p>

有没有办法做到这一点?

3 个答案:

答案 0 :(得分:2)

使它成为一种类方法:

@classmethod
def new(cls, z):
    return cls(z)

答案 1 :(得分:1)

理想情况下,而不是:

def new(self,z):
    n = A(z)
    return n

你有:

def new(self, z):
    n = self.__class__(z)
    return n

这样,您就可以使用该方法调用该方法,而不是硬编码您正在创建新实例的类。

但是,既然您已经提到过您无法修改基类,那么您有两种选择:

  1. 覆盖派生类
  2. 中的方法
  3. 猴子补丁基类
  4. 请求维护基类的人为您进行此更改
  5. 您已经说过不想覆盖它,因为它对便携性不利。我认为这不是真的 - 如果基类可能会更新以使其公共API的行为发生变化,那么它的可移植性已经很糟糕,因为谁知道什么是重大变化它可能会介绍。如果行为保持一致(即使实现发生变化),覆盖也应该是安全的。

    另一种选择是修补基类。这与基类中的覆盖具有相同的问题,不同之处在于其他子类也会获得行为 - 而不仅仅是那些从B继承的行为。

    你是这样的补丁(在课程定义之外):

    def new_new(self, z):
        n = self.__class__(z)
        return n
    
    A.new = new_new
    

答案 2 :(得分:0)

使用__class__

n = self.__class__(z)
return n

...

@ jonrsharpe的答案更好