2016-02-04 36 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