How does Python's super() work with multiple inheritance?
我正在查看上面的问题/答案,让自己真的很困惑
53 class First(object):
54 def __init__(self):
55 print "first"
56
57 class Second(First):
58 def __init__(self):
59 super(Second, self).__init__()
60 print "second"
61
62 class Third(First):
63 def __init__(self):
64 print "third"
65
66 class Fourth(Second, Third):
67 def __init__(self):
68 super(Fourth, self).__init__()
69 print "thats it"
第四()
第三
第二
多数民众赞成
53 class First(object):
54 def __init__(self):
55 print "first"
56
57 class Second(First):
58 def __init__(self):
59 #super(Second, self).__init__() <---- commented out
60 print "second"
61
62 class Third(First):
63 def __init__(self):
64 print "third"
65
66 class Fourth(Second, Third):
67 def __init__(self):
68 super(Fourth, self).__init__()
69 print "thats it"
第四()
第二
多数民众赞成
有人可以向我解释一下,为什么顶部打印件"third"
和底部打印件没有?为什么会幕后发生什么?
我觉得在我看不到的场景背后会发生某种顺序/顺序。
- 第四。 mro
在第二期评论超级 (,,,,)
超级二 (,,,,)
答案 0 :(得分:4)
super
实际上并没有调用超类。它根据方法解决顺序(MRO)调用下一个方法。看起来您的示例类的MRO如下:
Fourth
Second
Third
First
也就是说,使用super
中的Fourth
可以获得Second
上的方法。使用super
中的Second
可以获得Third
上的方法。等
在第一个例子中:
Fourth.__init__
被召唤。Fourth.__init__
通过Second.__init__
致电super
。Second.__init__
通过Third.__init__
致电super
。Third.__init__
打印“第三”Second.__init__
打印“第二个”Fourth.__init__
打印“就是这样”。在第二个例子中:
Fourth.__init__
被召唤。Fourth.__init__
通过Second.__init__
致电super
。Second.__init__
打印“第二个”Fourth.__init__
打印“就是这样”。所以,是的,更改super
中的Second
来电会改变Third
上的内容是否被调用,即使Third
不是Second
的超类}。这确实令人困惑。我建议阅读"Python's Super is nifty, but you can't use it"。这就是我读到的解释,让上述内容对我有意义。
答案 1 :(得分:3)
MRO不是嵌套层次结构。它是一个遵循一组约束的平面列表,即每个类必须在它的基类之前,并且这些基类必须以子类声明中提到的相对于彼此的顺序存在。
通过打印Fourth.__mro__
,我们可以看到示例中的MRO是:
(<class '__main__.Fourth'>,
<class '__main__.Second'>,
<class '__main__.Third'>,
<class '__main__.First'>,
<type 'object'>)
对super
的每次调用都将调用MRO中的下一个方法。您可以将super
个调用的数量视为您将要下降的MRO中的零索引“深度”。
由于第一个代码段中有super
两次调用,因此调用Second.__init__
和Third.__init__
(此外,当然还要调用直接类'init方法)。同样,在第二个代码段中,您只需拨打一次super
,这意味着只会调用Second.__init__
。