2017-10-07 77 views
1

我有兩個類(Parent1和Parent2),實現一些方法。然後我有兩個類(Child1和Child2)應該從它們相應的Parent繼承並實現一些功能。問題是Child1和Child2具有完全相同的邏輯,所以我希望有人能指出我的解決方案的可重用性的方向。我正在研究條件繼承,但不確定,因爲它在我來自的語言中並不是真正的東西。Python相同的代碼,但不同的繼承

簡單的例子只是爲了得到一個想法:

# In file1 
class Parent1(): 
    def main_method(self): 
     # Parent 1 implementation 
     self.arr = [1, 2, 3] 

# In file2 
class Parent2(): 
    def main_method(self): 
     # Parent 2 implementation 
     self.arr = [2, 4, 6] 

# In file3 
class Child1(Parent1): 
    def main_method(self): 
     Parent1.main_method(self) 
     # Child logic for main_method 
     print self.arr 

# In file4 
class Child2(Parent2): 
    def main_method(self): 
     Parent2.main_method(self) 
     # Child logic for main_method 
     print self.arr 

回答

3

有兩個選項可以想到。首先,使用Mixin通過繼承添加功能。我覺得這是Pythonic更多的解決方案。請注意,Mixin將需要成爲第一個繼承的類,以便它首先出現在MRO中(否則將找到Parent方法)。

class Parent(): 
    def main_method(self): 
     self.arr = [1, 2, 3] 

class MethodMixin(): 
    def main_method(self): 
     super(MethodMixin, self).main_method() 
     print(self.arr) 

class Child(MethodMixin, Parent): pass 

我以前見過這種方法,並取得了巨大的成功。例如,django-rest-framework在其Viewset代碼中使用此模式。

第二種選擇是使用元類在創建類時動態地將方法添加到Child類。

class MethodMeta(type): 
    def __new__(cls, name, parents, dct): 
     new_cls = super(MethodMeta, cls).__new__(cls, name, parents, dct) 

     def main_method(self): 
      super(new_cls, self).main_method() 
      print(self.arr) 

     new_cls.main_method = main_method 
     return new_cls 

class Child(Parent, metaclass=MethodMeta): pass 

上面的代碼片段使用Python 3.X元類語法。如果您想在Python 2.X中使用元類,則必須將其添加爲名爲__metaclass__的類變量。請注意,這種元類方法不能很好地擴展;如果你想在元類中添加10個方法,它將比Mixin替代方案更加複雜。

+0

就像mixin解決方案的外觀一樣。然後,我可以創建從Parent1繼承的Child1並創建從Parent2繼承的Child2。然後,我只是混合到child1和child2我需要在兩個地方重用的方法? – kjonsson

+0

如果你的意思是'class Child1(MethodMixin,Parent1):pass'和'class Child2(MethodMixin,Parent2):pass',那麼是的。 –

+0

有兩個問題。我在哪裏調用超級方法來__init__父母?如果他們的孩子實施一些差異,我可以跳過傳遞和實施這些方法嗎? – kjonsson

0

這似乎更符合邏輯,我認爲家長成爲孩子的,副versa.Lets。你可以這樣做

class Parent(): 
    def main_method(self): 
     //the child logic in your code 
     return self.arr 

class Child1(Parent): 
    def main_method(self): 
     //parent1 logic in your code 
     self.arr = [1,2,3] 
     Parent.main_method(self) 
      print self.arr 

class Child2(Parent): 
     def main_method(self): 
      //parent2 logic in your code 
      self.arr = [2,4,6] 
      Parent.main_method(self) 
      print self.arr 

我真的不知道這是有意義的實際代碼但通常commin邏輯在父類中規定,而子類添加邏輯代碼。無論如何希望這會有所幫助。

+0

父母是完全不同的,孩子也是如此。類和不同方法實現之間的多個附加方法。它來自一個龐大的代碼庫,我沒有寫,只是想擺脫一些代碼重複。 – kjonsson

+0

哦,我還以爲childs增加了相同的邏輯代碼,如你所說「問題是Child1和Child2有完全相同的邏輯」 – doze

+0

啊你真的沒錯。問題是父母是繼承和實現QT代碼的複雜類,並且由一位已經離開的開發人員編寫而成。希望通過某種方式將子代碼複製到一個類中並有條件地繼承或類似的東西來修復代碼重複。 – kjonsson