2011-06-09 19 views
6

我有一個類:混入,多繼承,構造函數和數據

class A(object): 
    def __init__(self, *args): 
     # impl 

也是一個「混入」,用一些數據和方法基本上是另一個類:

class Mixin(object): 
    def __init__(self): 
     self.data = [] 

    def a_method(self): 
     # do something 

現在我創建A的一個子類與mixin:

class AWithMixin(A, Mixin): 
    pass 

我的問題是我想A和Mixin的構造函數都被調用。我考慮給AWithMixin一個自己的構造函數,其中超類被調用,但超類的構造函數有不同的參數列表。什麼是最好的解決方案?

+1

什麼是阻止你調用兩個基類的構造函數(使用它們的適當的ar來自'AWithMixin .__ init__'的? – NPE 2011-06-09 15:08:47

+0

這已經被深入解答了。請參閱http://stackoverflow.com/a/6100595/763269 – 2017-04-06 20:54:52

回答

8

我是相當新的OOP過,但什麼是這個代碼的問題:

class AWithMixin(A, Mixin): 
    def __init__(self, *args): 
     A.__init__(self, *args) 
     Mixin.__init__(self) 
+2

這是最佳解決方案,我始終使用它。但是,如果'A'和'Mixin'擴展了某些類(例如'Base')並且都調用'Base .__ init __()',則可以使用[super()函數](http:// stackoverflow)。 COM/q/576169)。這是複雜的恕我直言,我建議知道,但如果可能避免它。 – brandizzi 2011-06-09 15:37:34

+0

@brandizzi,正如我在回答中所說的,我是OOP的新手。我看起來超級功能,但不明白。如果我在這個類[code] super(AW​​ithMixin,self).__ init __()[/ code]上說過,我怎樣才能調用A .__ init__和Mixin .__ init__兩者?並指定不同的參數? – utdemir 2011-06-09 17:10:38

+1

問題是這個解決方案不是特別可擴展的,它完全忽略了封裝的重點,並且它以錯誤的順序指定了mixin。如果您想要覆蓋mixin中的方法,那麼該mixin將獲取對該方法的控制權,並且應該負責在超類中調用相同的方法。 mixin採用不同的參數列表表明它的編碼不正確/不適用於該子類 - 它違反了[LSP](http://en.wikipedia.org/wiki/Liskov_substitution_principle)) 。 – quodlibetor 2013-08-29 20:49:35

10
class A_1(object): 
    def __init__(self, *args, **kwargs): 
     print 'A_1 constructor' 
     super(A_1, self).__init__(*args, **kwargs) 

class A_2(object): 
    def __init__(self, *args, **kwargs): 
     print 'A_2 constructor' 
     super(A_2, self).__init__(*args, **kwargs) 

class B(A_1, A_2): 
    def __init__(self, *args, **kwargs): 
     super(B, self).__init__(*args, **kwargs) 
     print 'B constructor' 

def main(): 
    b = B() 
    return 0 

if __name__ == '__main__': 
    main() 
  1. A_1構造
  2. A_2構造
  3. 乙構造