2013-10-14 57 views
6

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

可能是Python的super()如何與多繼承協同工作的副本?](http://stackoverflow.com/q/3277367/832621)? –

+4

@SaulloCastro但這就是我鏈接到的問題...... – ealeon

+0

@ealeon看看'Fourth .__ mro__',這就是'super()'的順序。 –

回答

4

super實際上並沒有調用父類。它根據方法解析順序(MRO)調用下一個方法。它看起來像你的示例類的MRO如下:

Fourth 
Second 
Third 
First 

也就是說,使用superFourth讓你在Second的方法。從Second使用super可以在Third上找到方法。等

在第一個例子:

  1. Fourth.__init__被調用。
  2. Fourth.__init__通過super致電Second.__init__
  3. Second.__init__調用Third.__init__通過super
  4. Third.__init__打印 「第三」
  5. Second.__init__打印 「第二」
  6. Fourth.__init__打印 「就是這樣」。

在第二個例子:

  1. Fourth.__init__被調用。
  2. Fourth.__init__調用Second.__init__通過super
  3. Second.__init__打印「秒」
  4. Fourth.__init__打印「就是這樣」。

所以,是的,在Second變化改變super呼叫是否上Third東西叫,即使Third不是一個超類的Second。這確實令人困惑。我推薦閱讀"Python's Super is nifty, but you can't use it"。這就是我讀到的解釋讓上面的內容對我有意義。

+2

另一篇相關文章:[Python的超級()被認爲超級!](http:// rhettinger.wordpress.com/2011/05/26/super-considered-super/) –

+1

是的是的。就是這個。 – ealeon

3

MRO不是嵌套層次結構。它是一個服從一組約束的扁平列表,即每個類必須位於其基類之前,並且這些基類必須以相同順序存在,因爲它們在子類聲明中提到。

通過打印Fourth.__mro__,我們可以看到在您的例子MRO是:

(<class '__main__.Fourth'>, 
<class '__main__.Second'>, 
<class '__main__.Third'>, 
<class '__main__.First'>, 
<type 'object'>) 

每次調用所掀起將調用的MRO下一個方法super。您可以將super調用的次數視爲您將下降到的MRO中的零索引「深度」。

由於在第一個片段中有兩個對super的調用,因此調用Second.__init__Third.__init__(另外,當然還有直接類的init方法)。同樣,在第二個片段中,您只需致電super,這意味着只會調用Second.__init__

+0

你是如何得到那個元組輸出的? –

+1

@NealEhardt' print Fourth .__ mro__' –