请考虑以下类,其中P1
和P2
是C
的父类:
class P1:
def f(self):
print('P1')
class P2:
def f(self):
print('P2')
class C(P1, P2):
def f(self):
print('C')
# super().f()
# super(P1, self).f()
c = C()
c.f()
当我运行此命令时,它打印C
。
如果我取消注释第一行super().f()
,那么它也会打印P1
因为super()
将从直接父级调用该方法,所以P1
如果我取消注释第二行super(P1, self).f()
,那么它也会打印P2
因为super(P1, self)
将从P1
的同级中调用该方法,所以P2
[我想知道的是,是否有任何方法可以通过一次调用f
函数从两个父类P1
和P2
中调用super()
方法,而不是像我一样两次调用它。做到了。
或者,是否有其他方法可以不使用super
功能呢?
没有很好的方法来精确地完成您想要的。但是,如果您可以同时修改P1
和P2
,则可以实现协作式多重继承,您只需要向具有该方法的no-op实现的两个父类中添加一个基类:
class GP: # grandparent base class
def f(self):
pass # do nothing
class P1(GP):
def f(self):
print("P1")
super().f()
class P2(GP):
def f(self):
print("P2")
super().f()
class C(P1, P2):
def f(self):
print("C")
super().f()
这是有效的,因为super
并不完全意味着“我的父母班级”。它的意思是“该对象的MRO中的下一个”。 MRO是方法解析顺序,基本上是在继承中搜索事物的顺序。在super()
中调用C
时,它将在P1
中找到方法。但是,当在super()
上(在P1
的实例上)调用C
时,它会调用P2
,因为C
实例的MRO为[C, P1, P2, GP, object]
。 P2
紧随P1
之后,因此被第二个super
调用选择。
GP
类是结束super
调用链所必需的。如果没有它,最后一个super
调用将解析为object
(这是所有继承树的根),并且由于没有这样的方法,您会得到一个错误。基类中的实现不需要执行任何操作,只需要最后不调用super
。