我有一段代码使用了超级继承和多重继承。
课程的结果是:
go A go!
go C go!
go B go!
go D go!
尽管我希望:
go A go!
go B go!
go D go!
根据我的理解:D因为MRO调用了类B因为go是在B中实现的。类B调用了其父A的super。A被执行了,没关系。然后我希望B继续执行,这意味着B被执行,最后D被执行。
但这当然是不对的。为什么它会进入C,因为go方法的定义在B中找到,然后它就不应该再在C中搜索了,这就是MRO的工作原理。它在头等舱找到,不应该再搜索了。完全困惑:(
class A(object):
def go(self):
print("go A go!")
class B(A):
def go(self):
super(B, self).go()
print("go B go!")
class C(A):
def go(self):
super(C, self).go()
print("go C go!")
class D(B,C):
def go(self):
super(D, self).go()
print("go D go!")
a = A()
b = B()
c = C()
d = D()
d.go()
最佳答案
这里有一段来自PyCon的优秀视频,作者是Raymond Hettinger(核心python开发人员)here。
最主要的收获是超级不叫你父母,而是叫你后代的祖先。因此,每当您调用super
,它就会返回到您实际调用该方法的实例,并在MRO中查找下一个类型(即使具有多重继承,这也是有保证的顺序,为什么class D(B,C)
与class D(C, B)
不同)。
在你的情况下,D的MRO是(D,B,C,A)。当D.go
调用super时,它调用B.go
。当它调用super时,它仍在使用D的MRO,所以它移到下一个类型,在您的情况下,C反过来调用A。最终的结果是,您的print语句在D的MRO中被反向执行。
There is also a blog by RH here如果你看不到youtube,也会有同样的话题。