Stu*_*Man 5 python oop multiple-inheritance super
class parent:
def __init__(self):
self.a=2
self.b=4
def form1(self):
print("calling parent from1")
print('p',self.a+self.b)
class child1(parent):
def __init__(self):
self.a=50
self.b=4
def form1(self):
print('bye',self.a-self.b)
def callchildform1(self):
print("calling parent from child1")
super().form1()
class child2(parent):
def __init__(self):
self.a=3
self.b=4
def form1(self):
print('hi',self.a*self.b)
def callchildform1(self):
print("calling parent from child2")
super().form1()
class grandchild(child1,child2):
def __init__(self):
self.a=10
self.b=4
def callingparent(self):
super().form1()
g=grandchild()
g.callchildform1()
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,当我调用 时g.callchildform1(),根据 MRO 规则,将首先在同一个类中搜索该方法,然后是第一个父级(此处为 child1),然后是第二个父级(child2)。正如预期的那样,它调用child1.callchildform1()并执行第一行print("calling parent from child1")。super().form1()但在此之后,我预计将执行下一行,该行将被调用parent.form1(),但这种情况不会发生。相反,child2.form1()正在被调用。请解释一下为什么会出现这种情况?
该文档对如何工作有很好的解释super():
super([type[, object-or-type]])返回一个代理对象,该对象将方法调用委托给该类型的父类或同级类。这对于访问类中已重写的继承方法很有用。
确定要搜索的
object-or-type方法解析顺序。搜索从类型之后的类开始。
例如,如果
__mro__ofobject-or-type是D -> B -> C -> A -> object并且 type 的值为B,则super()搜索C -> A -> object。
super()等价于表达式super(__class__, self)where__class__是一个类对象,在该类对象的方法中super()调用了 。例如,super()本质上grandchild.callingparent(self)是super(grandchild, self)。内部super()函数child1.callchildform1(self)是super(child1, self).
MRO对于grandchild是(<grandchild>, <child1>, <child2>, <parent>, <object>). 因此,根据上述文档摘录,当super().form1()在 中调用时child1.callchildform1(),相当于,从序列中紧随其后的类开始super(child1, self)搜索方法form1,并且第一个与方法匹配的类是。child1MROform1child2
发生这种情况是因为您正在使用钻石继承结构和MRO 的基础原则:
对于多重继承层次结构,线性化的构造更加麻烦,因为构造尊重局部优先顺序和单调性的线性化更加困难。
在设计这样的层次结构时,需要遵循合作继承的方法,可以在这篇已经很经典的文章中找到解释。