我有以下类结构:
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__
(以及这是否真的有效)。我真的更喜欢解决课堂内问题的解决方案。
答案 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)
应公开与C
或A
相同的API,B
可以覆盖C
:
__getattr__