我有以下类结构:
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)
的实现是完全一样的,并不真正关心它继承自哪个类。概念上的区别仅在于 A
和 B
(并且这些需要作为单独的类保存)。我不想为 C
和 D
编写单独的定义,而是希望能够从 A
或 B
动态继承基于在创建 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)
”的实现是相同的,他们实际上并不关心 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)
如果 C
应该公开与 A
或 B
相同的 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/