Python метаклассы - PullRequest
       17

Python метаклассы

6 голосов
/ 06 марта 2009

Я хакерские классы в Python, как это:

def hack(f,aClass) :
  class MyClass(aClass) :
     def f(self) :
       f()
  return MyClass

A = hack(afunc,A)

Что выглядит довольно чисто для меня. Он принимает класс A, создает новый класс, производный от него, который имеет дополнительный метод, вызывающий f, и затем переназначает новый класс на A.

Чем это отличается от взлома метаклассов в Python? Каковы преимущества использования метакласса по сравнению с этим?

Ответы [ 3 ]

5 голосов
/ 06 марта 2009

Определение класса в Python является экземпляром типа (или экземпляром подкласса типа). Другими словами, само определение класса является объектом. С метаклассами у вас есть возможность управлять экземпляром типа, который становится определением класса.

Когда вызывается метакласс, у вас есть возможность полностью переписать определение класса. У вас есть доступ ко всем предлагаемым атрибутам класса, его предкам и т. Д. Вы можете не только внедрить метод или удалить метод, но и радикально изменить дерево наследования, тип и почти любой другой аспект. Вы также можете связать метаклассы вместе для очень динамичного и полностью запутанного опыта.

Полагаю, реальная выгода заключается в том, что тип класса остается типом класса. В вашем примере введите:

a_inst = A()
type(a_inst)

покажет, что это экземпляр MyClass. Да, isinstance(a_inst, aClass) вернет True, но вы ввели подкласс, а не динамически переопределенный класс. Различие там, вероятно, в ключе.

Как указывает rjh, анонимный внутренний класс также влияет на производительность и расширяемость. Метакласс обрабатывается только один раз, и в тот момент, когда класс определен, и никогда больше. Пользователи вашего API также могут расширять ваш метакласс, поскольку он не заключен в функцию, поэтому вы получаете определенную степень расширяемости.

Эта немного старая статья на самом деле имеет хорошее объяснение, которое точно сравнивает подход «декорирования функций», который вы использовали в примере с метаклассами, и показывает историю развития метакласса Python в этом контексте: http://www.ibm.com/developerworks/linux/library/l-pymeta.html

1 голос
/ 27 мая 2009

Вы также можете использовать type вызываемый.

def hack(f, aClass):
    newfunc = lambda self: f()
    return type('MyClass', (aClass,), {'f': newfunc})

Я считаю использование type самым простым способом попасть в мир метаклассов.

1 голос
/ 03 мая 2009

Метакласс - это класс класса. ИМО, парень здесь покрыл это вполне исправно, включая некоторые варианты использования. См. Вопрос переполнения стека "MetaClass", " new ", "cls" и "super" - что это за механизм точно? .

...