2016-02-22 135 views
1

我有一個類的集合,A1,A2,A3等,它們都有方法m()。我也有類B的方法m()。我想很容易地創建C1,C2,C3等類,它們從B類調用m(),同時也具有A1,A2,A3等所有其他屬性...Mixin覆蓋繼承的方法

我遇到的問題,然而,在C1類中,來自B類的方法m()應該從A1類呼叫m()

我很難把我想要的東西放入文字中,但我目前正在考慮這樣做的方式是使用mixins。 C1會從A1繼承,並混入B.但是,我不知道如何讓B中的m()從其中一個A類調用正確的m()

所以,我的兩個問題:

  • 是否有什麼,我試圖做一個名字嗎?
  • 這樣做的正確方法是什麼?

編輯:按照要求,一個具體的例子: 方法m(p)在A1,A2,A3等所有計算矩陣M,對於一些參數p。我想創建類C1,C2,C3等,它們的行爲方式與A1,A2,A3,相同,的方法爲m()。新方法m()需要一個長度爲N的參數p的較長列表,然後我們計算A*.m() N次,然後返回總和。

計算總和m()的代碼對於所有A *類都是相同的。在上面提出的混合輸入解決方案中,求和碼將在B中.B和A1都將被繼承以形成C1。然而,來自B的C1中的方法m()必須呼叫A1.m()

+0

你能舉一些例子嗎? – Yen

回答

1

我想你只是需要super重定向調用父或兄弟類(取決於MRO)。

例如:

class A1(object): 
    def m(self): 
     print('Calling method m of class A1') 
     self.data *= 2 

class A2(object): 
    def m(self): 
     print('Calling method m of class A2') 
     self.data *= 3 

class A3(object): 
    def m(self): 
     print('Calling method m of class A3') 
     self.data *= 4 

class B(object): 
    def m(self, p): 
     print('Calling method m of class B') 
     for i in range(p): 
      # You haven't specified which python you are using so I assume 
      # you might need to most explicit variant of super(). 
      # Python3 also allows just using super().m() 
      super(B, self).m() 

class C1(B, A1): 
    def __init__(self, value): 
     self.data = value 

只是測試它:

a = C1(10) 
a.m(10) 

打印:

Calling method m of class B 
Calling method m of class A1 
Calling method m of class A1 
Calling method m of class A1 
Calling method m of class A1 
Calling method m of class A1 
Calling method m of class A1 
Calling method m of class A1 
Calling method m of class A1 
Calling method m of class A1 
Calling method m of class A1 

和保存的值:

a.data 
# returns 10485760 

定義其他C作品太:

class C2(B, A2): 
    def __init__(self, value): 
     self.data = value 

a = C2(10).m(2) 
#Calling method m of class B 
#Calling method m of class A2 
#Calling method m of class A2 


class C3(B, A3): 
    def __init__(self, value): 
     self.data = value 

a = C3(10).m(1) 
#Calling method m of class B 
#Calling method m of class A3 

當然你會希望另一邏輯,可能需要從.m()返回而不是就地修改值,但我認爲你可以運作他們自己。

您正在查找的單詞可能是MRO (method resolution order)。希望這可以幫助你。

另外感興趣的可能是super (Python2),super (Python3)的文檔。

而你總是可以通過調用.mro()方法檢查類的MRO

print(C1.mro()) 
[<class '__main__.C1'>, <class '__main__.B'>, <class '__main__.A1'>, <class 'object'>] 

所以Python開始通過檢查C1有一個方法m,如果不檢查BB有一個,所以它被執行。 super調用然後再次進入MRO並檢查下一個類(A1)是否有方法m,然後執行該方法。

+1

您可能想澄清一下,super()並不總是調用父對象,它會在* MRO *中的下一個類中查找請求的屬性。正如在這種情況下,它可以找到一個兄弟姐妹班。 – Blckknght