2013-01-07 40 views
33

在Python中,如何選擇調用哪個Parent的方法?假設我想調用父ASDF2的__init__方法。似乎我必須指定ASDF1在超()..?如果我想打電話給ASDF3的__init__,那麼我必須指定ASDF2?!Python的多重繼承:選擇要調用哪個super()

>>> class ASDF(ASDF1, ASDF2, ASDF3): 
    def __init__(self): 
     super(ASDF1, self).__init__() 


>>> ASDF() 
ASDF2's __init__ happened 
>>> class ASDF(ASDF1, ASDF2, ASDF3): 
    def __init__(self): 
     super(ASDF2, self).__init__() 


>>> ASDF() 
ASDF3's __init__ happened 

對我來說似乎是瘋狂的。我究竟做錯了什麼?

回答

47

這不是super()的用途。 Super基本上以特定的順序挑選一個(或全部)父母。如果你只想要把一個單親的方法,這樣做

class ASDF(ASDF1, ASDF2, ASDF3): 
    def __init__(self): 
     ASDF2.__init__(self) 
10

super調用該方法解析順序的一個方法。在線性繼承樹中,這將是直接父類中的方法。

在這裏,你有三個父母,並且從ASDF1的下一個__init__方法的角度是ASDF2。一般來說,安全的做法是將繼承列表中的第一個類傳遞給super,除非您知道爲什麼要執行其他操作。

所有這一切的目的是爲了減輕你不得不明確選擇哪個方法來調用。這裏的問題是爲什麼你不想調用所有的超類__init__方法。

在python中使用super有相當多的文獻,我建議你谷歌的主題,並閱讀什麼結果。

4

你傳遞ASDF1(你的父類之一)作爲super()的第一個參數。不要這樣做。相反,您應該將ASDF作爲super()的第一個參數傳遞。

Python 2.7 documentation for super()

引述的Python 2.7文檔,一個典型的超調用如下:

class C(B): 
    def method(self, arg): 
     super(C, self).method(arg) 

注意,第一個參數超級這裏是C,這是當前類。不要將B(父類)傳遞給super()。

確定方法解析順序(MRO)超級跳過作爲其第一個參數傳入的類,並開始查看該類的父母和兄弟姐妹。因此,當您將ASDF1作爲super()的第一個參數傳遞時,它會跳過ASDF1並開始使用ASDF2進行搜索。這就是爲什麼ASDF2的__init__被稱爲。


在Python 3中,您不必再傳遞當前類。

class C(B): 
    def method(self, arg): 
     super().method(arg) # This does the same thing as: 
           # super(C, self).method(arg) 
           # (Python 3 only)