Хотя это, безусловно, может быть сделано с метаклассами, вы можете делать то, что вы хотите без них, потому что в Python классы сами по себе являются объектами.Это означает, что, что удивительно, по сути, требуется не что иное, как перевод кода C ++ почти один к одному.Помимо того, что это относительно несложно из-за этого, он также будет работать без изменений в Python 2 и 3.
def template(class_T):
"""Factory function to create subclasses of class_T."""
class Foo(class_T):
def fun(self):
print('%s.fun()' % self.__class__.__name__)
Foo.__name__ += '_' + class_T.__name__ # rename the subclass to reflect its heritage
return Foo
class Base1:
def bar(self):
print('Base1.bar()')
class Base2:
def bar(self):
print('Base2.bar()')
Foo_Base1 = template(Base1)
print('Foo_Base1 base classes: {}'.format(Foo_Base1.__bases__))
Foo_Base2 = template(Base2)
print('Foo_Base2 base classes: {}'.format(Foo_Base2.__bases__))
subclass1 = Foo_Base1()
subclass1.fun()
subclass1.bar()
subclass2 = Foo_Base2()
subclass2.fun()
subclass2.bar()
Вывод:
Foo_Base1 base classes: (<class __main__.Base1 at 0x00A79C38>,)
Foo_Base2 base classes: (<class __main__.Base2 at 0x00A79DC0>,)
Foo_Base1.fun()
Base1.bar()
Foo_Base2.fun()
Base2.bar()
Код в (названный без воображения) Функция template()
является примером того, что обычно называют фабрикой классов или реализацией шаблона Factory .Так, кстати, вы можете найти мой ответ на вопрос Что такое Фабрика классов? информативно.
Редактировать: Добавлен код для создания разных имен классов для каждого возвращенного подкласса, что было вдохновлено @ aaronasterling (в уже удаленном комментарии) о возможной путанице при отладке, если производимый класс всегда имеет одинаковоеимя.