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

标签 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(并且这些需要作为单独的类保存)。我不想为 CD 编写单独的定义,而是希望能够从 AB 动态继承基于在创建 C/D实例时提供的参数(最终是 C D 必须同名)。

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

最佳答案

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

无论如何,

  • class C(A): ......... class C(B): ..... 甚至无效,结果只有 类 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)”的实现是相同的,他们实际上并不关心 AB。使用组合对我来说似乎更正确。然后你可以按照以下方式做一些事情:

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) 

如果 C 应该公开与 AB 相同的 API,C 可以覆盖 __getattr__:

class A:
    def foo(self):
        print('foo')

class C:
    def __init__(self, obj):
        self.obj = obj

    def __getattr__(self, item):
        return getattr(self.obj, item)

C(A()).foo()
# foo

关于python - 如何在初始化时动态继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50044254/

相关文章:

python - 我的问题是编写一个 python 程序来从文件中读取 2 个数字,并将这 2 个数字的 gcd 和 lcm 写入第二个文件。这是我的代码

python - boto s3 - 使用数组写入一个 csv 文件

python-3.x - pip 安装成功后,aws cli 无法在 Jupyter 中工作?

swift - 使用默认值参数覆盖函数时,如何保持默认值与父类(super class)相同?

c++模板不带参数使用

python pandas date time 输出日期相同

python - Tensorflow QueueRunner 与 py_func enqueue_op : How to use?

python - 使用正则表达式提取数字

python - 如何在 django 模板中每个循环渲染 3 个元素?

c++ - 从构造函数调用构造函数