我的基类有一个返回自身实例的方法。当我编写我的子类时,有没有办法让这个实例成为我的子类而不是基类的实例,而不修改基类的代码或将整个基类方法重写到我的子类方法中?
示例:
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>
有没有办法做到这一点?
答案 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
这样,您就可以使用该方法调用该方法,而不是硬编码您正在创建新实例的类。
但是,既然您已经提到过您无法修改基类,那么您有两种选择:
您已经说过不想覆盖它,因为它对便携性不利。我认为这不是真的 - 如果基类可能会更新以使其公共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的答案更好