2016-02-22 18 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