如何解决方法解析顺序MRO如何在此Python代码中工作
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()
在上面的代码中,当我调用g.callchildform1()
时,根据MRO规则,将首先在同一类中搜索该方法,然后是第一个父级(此处为child1),然后是第二个父级(child2)。
如预期的那样,它将调用child1.callchildform1()
并执行第一行print("calling parent from child1")
。但是在此之后,我希望执行super().form1()
的下一行parent.form1()
,但这不会发生。相反,正在调用child2.form1()
。请解释为什么会发生这种情况?
解决方法
documentation对super()
的工作方式有很好的解释:
super([type[,object-or-type]])
返回将方法调用委托给父级或同级类的代理对象。这对于访问已在类中重写的继承方法很有用。
object-or-type
确定要搜索的方法解析顺序。搜索从该类型后的紧随其后的开始。
例如,如果
__mro__
中的object-or-type
为D -> B -> C -> A -> object
,并且type的值为B
,则super()
搜索C -> A -> object
。 / p>
super()
等效于表达式super(__class__,self)
,其中__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
方法的搜索从child1
序列中MRO
之后的类,并且具有form1
方法的第一个匹配类是child2
。
之所以发生这种情况,是因为您使用的是钻石继承结构以及MRO的principles:
具有多个继承层次结构,线性化的构建比较麻烦,因为要构建尊重本地优先级排序和单调性的线性化更加困难。 >
在设计这样的层次结构时,需要遵循合作继承的方法,在这种已经很经典的article中可以找到解释。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。