python中的组合继承

时间:2016-12-09 00:02:11

标签: python oop inheritance software-design

我正在寻找有关如何构建我将要开展的项目的建议。

我有一个基类,有一些方法。

class Base(object):
  def method1(self):
    # some code
  def method2(self):
    # some code
  def method3(self):
    # some code
... and some other methods

对于我的项目,我无法修改Base类,我必须固有它才能应用我的项目要求。

我有几个要求可能启用或不启用。取决于给定的配置。即我希望能够覆盖method1(),method2(),method3()或它们的任意组合。

另一种方法是构造几个继承类。

class Child1(Base):
  def method1(self): 
    # some code

class Child2(Base):
  def method2(self): 
    # some code

class Child3(Base):
  def method3(self): 
    # some code

然后可以使用多重继承来应用它们的任何组合。然而,这种方法不能很好地覆盖所有可能的组合......(例如,如果我有Child4()会发生什么?)

另一种选择是只有一个继承类,并使用if子句来选择是调用super方法还是应用派生行为。

class Child(Base):
  def method1(self): 
    if not self.override1:
      # call super
    else:
      # some code

  def method2(self): 
    if not self.override2:
      # call super
    else:
      # some code

  def method3(self): 
    if not self.override3:
      # call super
    else:
      # some code

我更赞成这个替代方案,但我觉得必须有一个更好的OO方法来做到这一点。

有任何想法或建议吗?

非常感谢

PS:我受限于python 2.7,而且由于我计划共享代码,我宁愿拥有一个普通python程序员(而不仅仅是高级程序员)容易理解的解决方案。

2 个答案:

答案 0 :(得分:2)

我喜欢它看起来易于管理的第一选择,没有代码重复:

class A:
    def one(self):
        return 'one |'
    def two(self):
        return 'two |'
    def three(self):
        return 'three |'
    def four(self):
        return 'four |'

class B(A):
    def one(self):
        return 'one foo |'

class C(A):
    def two(self):
        return 'two foo |'

class D(A):
    def three(self):
        return 'three foo |'

class BC(B, C):
    pass
class CD(C, D):
    pass
class BD(B, D):
    pass

现在你有七件事可供选择。如果需要,您可以轻松地告诉它在运行时是什么类型的事情:

>>> bc = BC()
>>> isinstance(bc, A)
True
>>> isinstance(bc, CD)
False
>>> isinstance(bc, BC)
True

你可能会发现你忘记了一些东西并且很容易添加:

#oops now I need this
class X(A):
    def four(self):
        pass
# and this $#%^!*
class B1(A):
    def one(self):
        return 'one bar |'

答案 1 :(得分:1)

请记住,类定义是执行代码。您可以有条件地定义或忽略子类中的方法:

class Child(Base):
    if something:
        def method1(self, etc):
            pass

这是一个例子。请注意,设置条件必须在类定义之前进行 - 这是不是动态参数:

#!python3
import sys

special = False

if "--special" in sys.argv:
    special = True


class Base:
    def method1(self):
        print("Base method1")


    def method2(self):
        print("Base method2")

class Child(Base):
    def method3(self):
        print("Child method3")

    if special:
        def method1(self):
            print("Child method1")


ch = Child()
ch.method1()
ch.method2()
ch.method3()

输出是:

$ python test.py --special
Child method1
Base method2
Child method3

$ python test.py
Base method1
Base method2
Child method3