2017-04-23 62 views
0

我有一个程序是这样的:Python的超级()工作?

class A(): 
    def go(self): 
     print("A") 


class B(A): 
    def go(self): 
     super().go() 
     print("B") 


class C(A): 
    def go(self): 
     super().go() 
     print("C") 


class D(A): 
    def go(self): 
     super().go() 
     print("D") 


class E(B, C, D): 
    def go(self): 
     super().go() 
     print("E") 


a = A() 
b = B() 
c = C() 
d = D() 
e = E() 

print(e.go()) 

这里是的输出:

A 
D 
C 
B 
E 
None 

我很好奇超()的工作流程,它是如何之前打印d,C B,为什么最后没有打印?详细的解释将不胜感激。

+4

您是否阅读过这方面的大量现有资源?例如,http://stackoverflow.com/q/3277367/3001761。你还有什么特别不明白的? – jonrsharpe

+0

@ cricket_007,因为它是A之后的MRO中的下一个,这就是为什么在实际基类之前加入混合(请参阅http://stackoverflow.com/q/10018757/3001761)。 – jonrsharpe

+1

请参阅Raymond Hettinger出色的博文,Super Considered Super,https://rhettinger.wordpress.com/2011/05/26/super-considered-super/以及来自PyCon 2015的演讲:https://www.youtube.com /手表?ν= EiOglTERPEo。您看到D,C,B顺序,因为这是Python的方法解析顺序(MRO)的工作原理。 – PurpleDiane

回答

2

如果你打电话help(e)你可以看到method resolution order

>>> e = E() 
>>> help(e) 
class E(B, C, D) 
| Method resolution order: 
|  E 
|  B 
|  C 
|  D 
|  A 
|  builtins.object 

既然你第一个电话super然后print输出将被完全逆转mro

A -> D -> C -> B -> E 

如果你有print s之前super -calls它会跟着MRO:

E -> B -> C -> D -> A 

然而E.go不返回任何东西(return None是隐含的,如果之前没有其他return),所以它会打印None所有的方法都被调用后。

+0

是的,我了解MRO部分。但是不应该在A之后打印B,因为B已经完成了它的super()调用,现在它应该打印它自己的部分? –

+0

@AnmolGulati即使继承不是线性的,MRO总是**线性**。所以当你使用'super()'时,它总是沿着MRO。 – MSeifert

+0

@AnmolGulati事情是python神奇地插入'C'和'D'_between_'B'和'A'。这是一个可怕的设计选择国际海事组织。 –