2

我得到的錯誤: 類型錯誤:__init __()到底需要2個參數(3給出)多重繼承和調用超()

當試圖實例從類頂級的對象:

超( Middle1,self).__ init __(name,「middle」)

class Base(object): 
    def __init__(self, name, type): 
     pass 

class Middle1(Base): 
    def __init__(self, name): 
     super(Middle1, self).__init__(name, "middle1") 

class Middle2(Base): 
    def __init__(self, name): 
     super(Middle2, self).__init__(name, "middle2") 

class Middle3(Base): 
    def __init__(self, name): 
     super(Middle3, self).__init__(name, "middle3") 

class Top(Middle1, Middle2, Middle3): 
    def __init__(self): 
     super(Top, self).__init__("top") 

# Here is where it produces the error 
if __name__ == '__main__': 
    Top() 

我對這個多重繼承問題不瞭解麼?

注:這是蟒蛇2.7

編輯

好了,所以我想,我覺得適合我的情況什麼的。這是等價的最終結果,我認爲它基本上是先強制深度,而不是調用super並調用每個__init__。

class Base(object): 
    def __init__(self, name, type): 
     pass 

class Middle1(Base): 
    def __init__(self, name, type = "middle1"): 
     super(Middle1, self).__init__(name, type) 

class Middle2(Base): 
    def __init__(self, name, type = "middle2"): 
     super(Middle2, self).__init__(name, type) 

class Middle3(Base): 
    def __init__(self, name, type = "middle3"): 
     super(Middle3, self).__init__(name, type) 

class Top(Middle1, Middle2, Middle3): 
    def __init__(self): 
     Middle1.__init__(self, "top") 
     Middle2.__init__(self, "top") 
     Middle3.__init__(self, "top") 

# No errors anymore 
if __name__ == '__main__': 
    Top() 
+0

這不是技術上的多重繼承。多類繼承是指一個類直接從多個父類繼承(並且在大多數編程語言中通常不支持)。 – apokryfos

+2

您是否檢查過您正在執行的代碼文件是您在此顯示的代碼文件?因爲此代碼不會產生該錯誤... – dhke

+0

你是對的。我編輯了代碼來顯示我的實際情況,現在它產生了這個錯誤。 – Esser420

回答

3

首先,你要看看Top方法解析順序:

>>> for c in Top.__mro__: print c 
... 
<class '__main__.Top'> 
<class '__main__.Middle1'> 
<class '__main__.Middle2'> 
<class '__main__.Middle3'> 
<class '__main__.Base'> 
<type 'object'> 

這有助於您瞭解哪些類每次通話代表super

您的錯誤是在考慮致電super(Middle1, self)是指(僅)基類BaseMiddle1。它沒有:它是指在self.__class__的MRO以下Middle1類。由於self.__class__Top,在線上的下一個類是Middle2,其__init__只有一個參數。

要從方法正確使用super,你需要確保該方法採用相同的論點類,因爲你無法預測哪些類的方法將通過查看代碼本身調用;它完全取決於啓動調用鏈的對象的類型,這可能是一個你還沒有意識到的類。

有兩個職位我建議您閱讀:

在一起,他們讓您很好地理解super何時可以正確使用以及如何避免您在此處看到的問題。

(在完全公開,我沒有看到任何職位最近,所以我會從試圖總結各提出的建議不要。)

+0

是的,主要是它,我期望它先深入然後從左到右。 – Esser420

0

你究竟如何實例化Top對象?

鑑於你上面的代碼,以下工作正常:

topObj = Top() 
    middleObj = Middle("middle") 
    baseObj = Base("base", "type") 
+0

我看到你編輯了你的示例代碼。事實上,使用多重繼承構造函數解析會變得令人困惑。 – krono