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

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

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

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?
  • Почему конечное повторение в lookbehind не работает в некоторых вариантах?
  • увеличить 1.53 фатальная ошибка python LNK1104 boost_python-vc110-mt-gd-1_53.lib
  • Вызов функций C в Python
  • Установка lxml для Python 3.4 в Windows x 86 (32 бит) с помощью Visual Studio C ++ 2010 Express
  • Как преобразовать строку C (char array) в строку Python, когда в строке есть символы, отличные от ASCII?
  • Расширения Python C - Почему вызываемые C-функции принимают аргументы и возвращают PyObject *
  • Динамическое связывание и Python SWIG (C ++) работает в C ++ сбой в python
  • Python - лучший язык программирования в мире.