Я узнаю о метаклассах в Python. Я думаю, что это - очень мощная техника, и я ищу хорошее использование для них. Я хотел бы некоторую обратную связь хороших полезных реальных примеров использования метаклассов. Я не ищу пример кода о том, как записать метакласс (существует много примеров бесполезных метаклассов там), но реальные примеры, где Вы применили технику и это было действительно соответствующее решение. Правило: никакие теоретические возможности, но метаклассы на работе в реальном приложении.
Я запущу с одного примера, который я знаю:
Нетерпеливое ожидание Ваших вкладов.
валидаторы FormEncode и Turbogears / Tosca виджеты.
Вас также могут заинтересовать class decorators: они могут быть написаны на основе последних релизов и охватывают многие случаи использования, которые ранее обрабатывались с помощью метаклассов.
SQLalchemy также использует их для декларативных моделей баз данных.
Извините, что мой ответ не сильно отличается от вашего примера, но если вы ищете примеры кода, то я нашел declarative
довольно читабельным.
В Python 2.6 и 3.1 стандартная библиотека Python предоставляет abc.ABCMeta
, мета-класс для абстрактных базовых классов («ABC»). Классы, использующие метакласс, могут использовать @abstractmethod и @abstractproperty для определения абстрактных методов и свойств. Мета-класс гарантирует, что производные классы переопределяют абстрактные методы и свойства.
Кроме того, классы, реализующие ABC без фактического наследования от него, могут регистрироваться как реализующие интерфейс, так что issubclass
и isinstance
будут работать.
Например, модуль collections определяет Последовательность ABC. Он также вызывает Sequence.register (tuple)
для регистрации встроенного типа кортежа
как Sequence
, хотя кортеж
не выполняет фактически наследуется от Последовательности
.
Единственный раз, когда я использовал метакласс, был написан механизм предупреждения об износе. Это было что-то вроде следующего - синтаксис может быть очень приблизительным, но код проиллюстрирует мою мысль легче, чем сложное предложение :
class New(object):
pass
class Old(object):
def __new__(self):
deprecation_warning("Old class is no more supported, use New class instead")
return New()
Реализация протокольных буферов в Python использует метаклассы для создания привязок Python, которые представляют ваш формат данных. Из учебника :
Важная строка в каждом классе:
__ metaclass__ = Reflection.GeneratedProtocolMessageType
. Хотя подробности того, как работают метаклассы Python, выходят за рамки этого руководства, вы можете думать о них как о шаблоне для создания классов. Во время загрузки метаклассGeneratedProtocolMessageType
использует указанные дескрипторы для создания всех методов Python, необходимых для работы с каждым типом сообщений, и добавляет их в соответствующие классы. Затем вы можете использовать полностью заполненные классы в своем коде.