Обратите внимание, что, поскольку различные метаклассы в Python обычно сложно объединить, это может быть полезно, если разрешить комбинирование созданного пользователем метакласса с библиотечным или stdlib-классом, при этом этот класс не должен быть явно объявлен как родительский для первого:

авно открыл метаклассы в Python.

По сути, метакласс в python - это класс, который создает класс. Есть много полезных причин, по которым вы хотели бы сделать это - любой тип инициализации класса, например. Регистрация классов на фабриках, комплексная проверка атрибутов, изменение работы наследования и т. Д. Все это становится не только возможным, но и простым.

Но в python метаклассы также являются простыми классами. Итак, я начал задаваться вопросом, может ли абстракция с пользой идти выше, и мне кажется, что она может и что:

метакласс соответствует или реализует роль в шаблоне (как в языках шаблонов GOF).мета-метакласс - это сам образец (если мы позволим ему создавать кортежи классов, представляющих абстрактные роли, а не только один класс)мета-мета-метакласс являетсяфабрика узоровчто соответствует группировке GOF-паттернов, например, Творческий, Структурный, Поведенческий. Фабрика, на которой вы можете описать случай проблемы определенного типа, и она даст вам набор классов, которые ее решат.мета-мета-мета-метакласс (насколько я мог судить), этофабрика картины фабрикифабрика, к которой вы, возможно, могли бы описать тип вашей проблемы, и это даст вам фабрику шаблонов, которую можно спросить.

Я нашел кое-что об этом в Интернете, но в основном не очень полезно. Одна проблема состоит в том, что разные языки определяют метаклассы немного по-разному.

Кто-нибудь еще использовал такие метаклассы в python / elsewhere, или видел, как это используется в дикой природе, или думал об этом? Какие есть аналоги на других языках? Например. в C ++ насколько глубока может быть рекурсия шаблона?

Я бы очень хотел исследовать это дальше.

 Mike A16 мар. 2011 г., 19:55
Обновление: давно прошло. Я часто использовал метаклассы и думаю, что они были полезны, но потом я вообще отказался от метаклассов. Причина в том, что, изучив взаимодействие с доменом и некоторые исследования IBM, я понял, что концепция типа, свойственного объекту, сама по себе ошибочна. Вместо этого тип зависит от того, чей запрос. Для птицы дерево - это просто место для строительства гнезда. Для лесоруба, источника дохода, для налогового инспектора, возможно, что-то еще.

Ответы на вопрос(5)

как я впервые понял метаклассы в Python, я продолжал задаваться вопросом «что можно сделать с помощью метамета-класса?». Это было по крайней мере 10 лет назад - и теперь, всего пару месяцев назад, мне стало ясно, что существует один механизм создания классов Python, который на самом деле включает в себя класс «мета-мета». И, следовательно, можно попытаться представить себе какое-то использование для этого.

Чтобы повторить создание объекта в Python: всякий раз, когда создается экземпляр объекта в Python путем «вызова» его класса с тем же синтаксисом, который используется для вызова обычной функции, класс__new__ а также__init__, То, что «управляет» вызовом этих методов в классе, является именно классом «метакласс»__call__ метод. Обычно, когда пишут метакласс в Python, либо__new__ или же__init__ Метод метакласса настраивается.

Итак, получается, что, написав класс «мета-мета», можно настроить его__call__ метод и, следовательно, контролировать, какие параметры передаются и метаклассу__new__ а также__init__ методы, и если какой-то другой код должен быть вызван до или после них. В итоге получается, что сами меткалсы обычно жестко закодированы, и нужно всего несколько, если они вообще есть, даже в очень больших проектах. Поэтому любая настройка, которая может быть выполнена при вызове «meta meta», обычно выполняется непосредственно в самом метаклассе.

И их, есть и другие, менее часто используемые метаклассы Python - можно настроить__add__ метод в метаклассе, чтобы определяемые ими классы были «добавляемыми», и создавали производный класс, имеющий два добавленных класса в качестве суперклассов. Этот механизм также отлично работает с метаклассами - поэтому, просто у нас «есть некоторый реальный код», следует пример класса «мета-мета», который позволяет составлять «метаклассы» для класса, просто добавляя их в объявление класса :

class MM(type):
    def __add__(cls, other):
        metacls = cls.__class__
        return metacls(cls.__name__ + other.__name__, (cls, other), {})

class M1(type, metaclass=MM):
    def __new__(metacls, name, bases, namespace):
        namespace["M1"] = "here"
        print("At M1 creation")
        return super().__new__(metacls, name, bases, namespace)

class M2(type, metaclass=MM):
    def __new__(metacls, name, bases, namespace):
        namespace["M2"] = "there"
        print("At M2 creation")
        return super().__new__(metacls, name, bases, namespace)

И мы видим, что работа на интерактивной консоли:

In [22]: class Base(metaclass = M1 + M2): 
    ...:     pass
    ...: 
At M1 creation
At M2 creation

Обратите внимание, что, поскольку различные метаклассы в Python обычно сложно объединить, это может быть полезно, если разрешить комбинирование созданного пользователем метакласса с библиотечным или stdlib-классом, при этом этот класс не должен быть явно объявлен как родительский для первого:

In [23]: import abc

In [24]: class Combined(metaclass=M1 + abc.ABCMeta):
    ...:     pass
    ...: 
At M1 creation

ймон Пейтон Джонс отметил, что Haskell позволяет метапрограммировать, используя классы типов, но что он действительно терзает всю жизнь. Вы можете использовать мета-мета-мета-мета и т. Д. На языке Haskell, но он никогда не слышал, чтобы кто-то использовал более 3 уровней косвенности.

Гай Стил указал, что это то же самое в Лиспе и Схеме. Вы можете заниматься метапрограммированием, используя обратные ссылки и уловки (вы можете думать о обратном ударе как о лямбде Python, вроде бы), но он никогда не видел, чтобы использовалось более 3 обратных ударов.

Предположительно они видели больше кода, чем вы или я, так что это лишь небольшое преувеличение, чтобы сказать, что никто никогда не выходил за пределы 3 уровня мета.

Если вы думаете об этом, большинство людей никогда не используют метапрограммирование, и два уровня довольно сложно обернуть вокруг. Я предполагаю, что три почти невозможно, и тот последний парень, который попробует четыре, оказался в убежище.

 Triptych06 мая 2011 г., 03:18
Вы действительно чувствуете, что сходите с ума, пытаясь пройти несколько уровней. +1 за упоминание о предоставлении убежища.

который некоторые люди, кажется, собираются сделать «общей реализацией шаблона». Как фабрика, которая может создать любой объект (в том числе другой завод), или интегрированная структура внедрения зависимостей, которой гораздо сложнее управлять, чем просто писать код, который на самом деледелает что-то.

Мне приходилось иметь дело с людьми, намеревающимися абстрагироваться до точки зрения пупка, когда я управлял проектом Zend Framework. Я отклонил кучу предложений по созданию компонентов, которые ничего не делали, они были просто волшебными реализациями шаблонов GoF, как будто шаблон был целью сам по себе, а не средством достижения цели.

Есть точка уменьшения отдачи от абстракции. Некоторая абстракция хороша, но в конечном итоге вам нужно написать код, который делает что-то полезное.

В противном случае это просточерепахи вниз.

 Richard Erickson09 апр. 2015 г., 21:16
Ваш пост напоминает мне оМашина фон Нейманаака монолиты из серии "Космическая одиссея".
 Marco Mariani02 дек. 2010 г., 12:14
Нам нужно придумать архитектурный образец Discworld
 Seth29 янв. 2010 г., 00:18
+1 для черепах!

Не стесняйтесь исследовать это дальше.

Однако обратите внимание, что вы связали шаблоны проектирования (которые являются просто идеями) с кодом (который является реализацией).

Хороший код часто отражает множество взаимосвязанных шаблонов проектирования. Там нет простого способа формализовать это. Лучшее, что вы можете сделать, - это хорошая картинка, хорошо написанные строки документов и имена методов, которые отражают различные шаблоны проектирования.

Также обратите внимание, что мета-класс - это класс. Это петля. Там нет более высокого уровня абстракций. На данный момент, это просто намерение. Идея мета-мета-класса не имеет большого значения - это мета-класс для мета-классов, что глупо, но технически возможно. Однако это всего лишь класс.

редактировать

«Действительно ли классы, которые создают метаклассы, настолько глупы? Как внезапно заканчивается их полезность?»

Класс, который создает класс, это хорошо. Вот и все. Тот факт, что целевой класс является мета-классом или абстрактным суперклассом или конкретным классом, не имеет значения. Метаклассы делают классы. Они могут создавать другие метаклассы, что странно, но они все еще просто создают классы метаклассов.

Утилита «внезапно» заканчивается, потому что в метаклассе, который создает другой метакласс, нет никакой реальной вещи, которая вам нужна (или даже может написать). Дело не в том, что это «внезапно» становится глупым. Там нет ничего полезного.

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

Цель OO - написать определения классов, которые моделируют объекты реального мира. Как таковой, метакласс иногда удобен для определения сквозных аспектов нескольких связанных классов. (Это способ сделать некоторое Аспектно-ориентированное Программирование.) Это все, что может сделать метакласс; это место для хранения нескольких функций, таких как__new__(), это не правильные части самого класса.

 martineau02 июл. 2018 г., 18:13
Для тех, кто хочет быстро поиграть с мета-метаклассом, есть реализацияSuperMeta в конце статьи Python Central под названиемКак технически работают метаклассы в Python 2 и 3, Я лично сделал это и узнал несколько вещей о том, что делает Python в фоновом режиме, когда мета (и мета-мета) класс участвуют в процессе. Однако после этого мне все еще неясно, насколько полезной, и в хорошей цели, может быть такая техника.
 Mike A29 янв. 2009 г., 05:03
Я уважаю ваши очки. Я должен был не приравнивать метаклассы как шаблоны / роли, а просто их реализацию. Но избежать формализации, потому что это может быть трудно? Действительно ли классы, которые создают метаклассы, настолько глупы? Как внезапно заканчивается их утилита? Даже метаклассы имеют сходство.
 S.Lott29 янв. 2009 г., 12:12
@ mike.amy: под «жестким» я подразумевал непостижимое. Не "немного сложно". Очень трудно - иногда невозможно - разделить несколько хорошо продуманных шаблонов дизайна на формализмы. Некоторые хорошие дизайнерские решения - это привычки, которые трудно формализовать.
Решение Вопроса

ляется объектом, и у каждого объекта есть класс. Это не означает, что иерархия уходит в бесконечность. Если я правильно помню, это выглядит примерно так:

5 -> Integer -> Integer class -> Metaclass -> Metaclass class -> Metaclass -> ... (он зацикливается)

Где '->' обозначает «является экземпляром».

 Mike A29 янв. 2009 г., 05:06
Спасибо, некоторые другие люди упомянули smalltalk. Мне придется выкопать мою скрипучую виртуальную машину и сравнить метаклассы smalltalk с python.

Ваш ответ на вопрос