如何在初始化时动态继承?

时间:2018-04-26 13:27:31

标签: python python-3.x inheritance metaclass

我有以下类结构:

class Base:
  def z(self):
    raise NotImplementedError()

class A(Base):
  def z(self):
    self._x()
    return self._z()

  def _x(self):
    # do stuff

  def _a(self):
    raise NotImplementedError()

class B(Base)
  def z(self):
    self._x()
    return self._z()

  def _x(self):
    # do stuff

  def _z(self):
    raise NotImplementedError()


class C(A):
  def _z(self):
    print(5)

class D(B):
  def _z(self):
    print(5)

C(A)D(B)的实现完全相同,并不关心它继承自哪个类。概念差异仅在AB(并且这些需要作为单独的类保存)。我希望能够根据创建C或D,而不是为AB编写单独的定义。 C / D的“实例(最终CD必须是同一名称。”

似乎元类可能有效,但我不确定如何将__init__参数传递给元类__new__(以及这是否真的有效)。我真的更喜欢解决课堂内问题的解决方案。

1 个答案:

答案 0 :(得分:1)

您是否考虑过使用合成而不是继承?看起来它更适合这个用例。有关详细信息,请参阅答案的底部。

无论如何,

  • class C(A): ......... class C(B): .....甚至无法生效,只会class C(B)定义。

  • 我不确定元类能否在这里帮到你。我认为最好的方法是使用type,但我很乐意纠正。

使用type的解决方案(可能会误导locals(),但这不是重点)

class A:
    def __init__(self):
        print('Inherited from A')

class B:
    def __init__(self):
        print('Inherited from B')

class_to_inherit = input()  # 'A' or 'B"

C = type('C', (locals()[class_to_inherit],), {})

C()

'A' or 'B'
>> A
Inherited from A

'A' or 'B'
>> B
Inherited from B


<强>组合物

在我的回答开头回溯到问题时,您要说明“C(A)”和“C(B)”的实现是相同的,并且实际上并不关心{{ 1}}或A。使用合成对我来说似乎更正确。然后你可以按照以下方式做点什么:

B

如果class A: pass class B: pass class C: def __init__(self, obj): # obj is either A or B instance, or A or B themselves self.obj = obj # or self.obj = obj() if obj is A or B themselves c = C(A()) # or c = C(A) 应公开与CA相同的API,B可以覆盖C

__getattr__