Рассматривали ли вы использование композиции вместо наследования? Кажется, что это гораздо больше подходит для этого варианта использования. Подробности смотрите в нижней части ответа.
В любом случае,
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)
" идентичны, и на самом деле им нет дела до A
или * 1033. *. Мне кажется более правильным использовать композицию. Тогда вы можете сделать что-то вроде:
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
должен предоставлять тот же API, что и A
или B
, 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