2011-06-09 78 views
1

我怎麼能初始化倍數超類中的蟒蛇..初始化倍數超類蟒蛇

例如:

class A (B, C): 
    def __init__(self, param): 
     B.__init__(self) 
     C.__init__(self, param) 
    # 
# 
+3

你的問題到底是什麼? – 2011-06-09 14:23:04

+6

您顯示的代碼有效。當然你知道這一點,因爲你試過了,而不是用SO作爲解釋器。那你在問什麼? – delnan 2011-06-09 14:28:34

回答

6

您的原始代碼工作。它非常清晰和可讀。呼叫簽名是明確的,並允許您使用A(p)A(param=p)實例化A

class A(B, C): 
    def __init__(self, param): 
     B.__init__(self) 
     C.__init__(self, param) 

也可以使用super。它提供了有吸引力的能力有一個調用來替換 兩個顯式調用B.__init__C.__init__super(A,self).__init__

class B(object): 
    def __init__(self, **kwargs): 
     print('B') 
     super(B,self).__init__(**kwargs) 

class C(object): 
    def __init__(self, **kwargs): 
     print('C') 
     self.param=kwargs.pop('param',None) 
     super(C,self).__init__(**kwargs) 

class A(B, C): 
    def __init__(self, **kwargs): 
     print('A') 
     super(A,self).__init__(**kwargs) 

a=A(param=1) 

# A 
# B 
# C 

使用super,但是,需要一個rather heavy price

  1. __init__調用簽名所有類別 必須是相同的。由於ACparam說法,但B 不,你必須修改所有 三到使用更明確(但 制服!)**kwargs說法。因此,呼叫簽名不再是明確的。

  2. 現在A只能被實例化 與A(param=p),並且不再與A(p)

  3. 更糟(如斯文Marnach指出 出在評論),傳遞給A必須在某一點的每個參數被關閉的kwargs因爲object彈出不接受任何參數。一旦類 (如C)彈出一個參數 的kwargs,沒有其他類(如 B)可以使用相同的參數名稱。因此,參數的命名需要所有類別之間的協調,即使理想情況下,BC應該彼此獨立。

  4. 該代碼有更多的鍋爐板殘餘物 和併發症。 閱讀起來不太容易。

因此,我一般喜歡避開super(一樣你原來的代碼),除非super遠遠超過上面提到的成本帶來的間接。

+0

不錯的總結。我想補充一點,這實際上*是一個帶有'object'的繼承鑽石。 'super()'調用鏈最終會調用'object .__ init __(self,** kwargs)',所以你必須確保所有的參數在這個時候已經被'kwargs'彈出。這在兩個類需要參數的情況下會產生問題,並且這個問題沒有真正的解決方案。 – 2011-06-09 18:32:51

+0

@Sven Marnach:謝謝你用'super'指出這個額外的問題。 – unutbu 2011-06-09 18:46:15

+0

我不知道爲什麼超級被稱爲語言,使事情不明確,而對大多數使用不起作用。 – dashesy 2015-04-15 01:07:48