Это требует переопределения Super.__new__
, чтобы превратить его в фабричную функцию.
class Super:
def __new__(cls, subclass_name, *args, **kwargs):
for sc in cls.__subclasses__():
if sc.__name__ == subclass_name:
return super().__new__(sc, *args, **kwargs)
raise ValueError("No such subclass")
class Sub1(Super):
pass
class Sub2(Super):
pass
assert type(Super('Sub1')) is Sub1
Это требует дополнительной работы, чтобы позволить вам непосредственно определить подкласс (так как Sub1()
вызовет Super.__new__
, так как Sub1.__new__
не определено).
Поэтому я бы предпочел метод выделенного класса, который принимает имя класса, а не переопределяет __new__
.
class Super:
@classmethod
def subclass_by_name(cls, name, *args, **kwargs):
for sc in cls.__subclasses__():
if sc.__name__ == name:
return sc(*args, **kwargs)
raise ValueError("No such subclass")
assert type(Super.subclass_by_name('Sub1')) is Sub1