Python - 选择要继承的类

时间:2016-12-17 12:21:40

标签: python inheritance multiple-inheritance

我想制作两个类A和B,其中B是A的轻微但重要的变体,然后制作第三个C类,它可以继承A或B并为它们添加功能。问题是,如何根据我的偏好告诉C继承A或B?

为了使事情更清楚,假设我有这个代码:

class A:

   def __init__(self, x, y):
       self.x = x
       self.y = y

   def first(self):
       return do_something(1)

   def second(self):
       return do_something(2)

   def third(self):
       return do_something(3)

   def start(self):
       self.first()
       self.second()
       self.third()

class B(A):

    def __init__(self, x, y, z):
        super().__init__(x, y)
        self.z = z

    def second(self):
        super().second()
        do_stuff()

    def third(self):
        do_other_stuff()

这是我使用的代码的简化版本。特别是,A代表制造系统的模拟器,而B代表同一制造系统的模拟器,并修改了主机床的行为。

现在,我想要的是添加代码来计算一些统计信息。它的作用是这样的:

class C(A):

    def __init__(self, *args):
        super().__init__(*args)
        self.stat = 0

    def second(self):
        super().second()
        self.stat += 1

    def third(self):
        super().third()
        self.stat *= 3

问题是C类的工作方式完全相同,无论我是继承A类(如上一个清单)还是B类(完全相同的代码,第一行class C(B):

我该怎么做?或者我使用不可行的方式?我认为一个理想的解决方案是能够在初始化C时选择要继承的类A或B.或者,也许,为了能够将类传递给C类继承。

我做了一些研究,我发现了聚合的可能性(我之前不知道),但我认为它没有用。作为最后一点,请注意A类可能有多达20-30个方法,当我使用类CI时,希望类A(或B,取决于它继承的方式)与之前添加的C中间块完全一样

P.S。我正在寻找一种可能优雅,没有代码重,“pythonic”的方式来做到这一点。我也非常期待你认为可以做得更好的一切建议。最后,我可以完全修改C类,但A类和B类必须保持不变(除小变化外)。

1 个答案:

答案 0 :(得分:1)

您可以使用新式类及其方法解析顺序

考虑这些定义:

class A(object):
    def __init__(self, x):
        pass

    def foo(self):
        print "A"

class B(object):
    def __init__(self, x, y):
        pass

    def foo(self):
        print "B"

您可以构建一个旨在为AB添加功能的mixin:

class Cmix(object):
    def foo(self):
        super(Cmix, self).foo()
        print "mix"

并分别从CmixA(或B)继承:

class CA(Cmix, A):
    pass

class CB(Cmix, B):
    pass

最后,您可以编写一个便利函数,根据参数的数量在CACB之间进行选择:

def C(*args):
    if len(args) == 1:
        return CA(*args)
    else:
        return CB(*args)

现在我们有了

C(1).foo()
# A
# mix
C(1, 2).foo()
# B
# mix

请注意,C不是真正的类,例如,您不能将其用作isinstance中的第二个参数。