Метакласс для параметризации Наследование

Я прочитал несколько руководств по метаклассам Python. Я никогда раньше не использовал его, но мне нужно что-то относительно простое, и все учебные пособия, похоже, направлены на более сложные варианты использования. Я в основном хочу создать класс шаблона, который имеет некоторое предварительно заданное тело, но берет его базовый класс в качестве параметра. Поскольку я получил идею из шаблонов C ++ / D, вот пример того, что код, который я хочу написать, будет выглядеть в C ++:

template<class T> class Foo : T { void fun() {} } 

  • Добавление базового класса в существующий объект в python
  • Как работает объект classmethod?
  • Переопределение метакласса по умолчанию () перед запуском Python
  • Оформление метода класса после @property
  • Динамически привязать метод к экземпляру класса в python
  • Переопределение специальных методов в экземпляре
  • Могу ли я определить __repr__ для класса, а не для экземпляра?
  • Действительные символы в имени класса python
  • Как функция, вызываемая внутри объявления класса?
  • Учитывая метод, как мне вернуть класс, который он принадлежит в Python 3.3 дальше?
  • 2 Solutions collect form web for “Метакласс для параметризации Наследование”

    Хотя это, безусловно, можно сделать с помощью метаклассов, вы можете делать то, что хотите, без них, потому что в классах 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() 

    Код в функции (unimaginatively-named) template() является примером того, что обычно называют фабрикой классов или реализацией шаблона Factory . Итак, кстати, вы можете найти мой ответ на вопрос: Что такое фабрика классов? информативный.

    Изменить: добавлен код для создания разных имен классов для каждого возвращаемого подкласса, который был вдохновлен проницательностью @ aaronasterling (в удаленном комментарии) о потенциальной путанице при отладке, если класс, созданный всегда, имеет одно и то же имя.

    Это не имеет смысла в Python, поскольку в нем нет шаблонов. Мое понимание параметризованных шаблонов в C ++ (что довольно неопределенно, поскольку прошло много лет с тех пор, как я посмотрел на них), заключается в том, что он действует как фабрика классов и может создавать подкласс любого класса, который вы ему даете, который имеет дополнительные методы или добавлены атрибуты.

    В Python вы можете сделать это с помощью заводской функции, которая берет класс и возвращает новый класс во время выполнения:

     In [1]: def subclassFactory(cls): ...: class Foo(cls): ...: def fun(self): ...: return "this is fun" ...: return Foo ...: In [2]: class A(object): ...: pass ...: In [5]: C = subclassFactory(A) In [6]: C Out[6]: <class '__main__.Foo'> In [7]: c = C() In [9]: c.fun() Out[9]: 'this is fun' In [10]: isinstance(c, A) Out[10]: True 
    Python - лучший язык программирования в мире.