2016-02-04 24 views
0

所以我们有下面的代码片段。我不明白为什么这样做。为什么super(B, self).go()解析为C类的go方法?在python为什么超级行为这种方式与多继承?

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!") 

d = D() 
d.go() 
# go A go! 
# go C go! 
# go B go! 
# go D go! 
+1

您是否阅读过MRO文档? https://www.python.org/download/releases/2.3/mro/不仅解释了什么,而且还解释了为什么*。 –

回答

5

尽管它的名字,super并不一定是指超类。 super(B, self)是指self的MRO中的类别B

你可以看到MRO针对d与

>>> D.__mro__ 
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) 

这意味着,从d.gosuper(D, self)B。当B.go被称为结果时,super(B, self)是指C,而不是A。这是因为self仍然是D的一个实例,所以它是D.__mro__,它规定了接下来要调用的内容,而不是B的静态超类。

要记住的最重要的事情有关super是里面Foo.go,你不知道什么super(Foo, self)将提到,因为你不知道,如果selfFoo实例或Foo的后代。

+0

需要注意的一点是:MRO代表“方法解析顺序” - 字面意思是执行“超级”方法的顺序。另一种考虑这个问题的方法是“你期望会发生什么”。很显然,'A.go'不应该被称为两次。所以如果它只应该被调用一次,当_should_被调用。答案是MRO订单。 – Hamish