Если MyMeta является метаклассом MyClass в Python 3.x, какие типы манипуляций MyMeta может делать с MyClass? - PullRequest
1 голос
/ 08 апреля 2020

Цель состоит в том, чтобы сравнить мощность метаклассов Python с системами метапрограммирования других языков, таких как Groovy, Xtend, Nemerle, CLOS, Open Java, BSJ (BackStage Java), Iguana / J, плагины компилятора для Scala, Cyan, et c.

Предположим, класс MyMeta является метаклассом класса MyClass.

Может ли MyMeta генерировать код в MyClass, который перехватывает получение и набор атрибутов экземпляра MyClass?

Может ли метод MyMeta вызываться при наследовании MyClass, даже если метакласс подкласса не является MyMeta?

Может ли метод MyMeta вызываться, когда метод MyClass переопределяется в подклассе, даже если метакласс подкласса не является MyMeta?

Может ли метод MyMeta вызываться, когда метод MyClass использует атрибут, который не был объявлен?

Может ли MyMeta обрабатывать AST MyClass или другое эквивалентное представление? Например, может ли MyMeta проверить, содержит ли каждый метод класса не более 20 операторов? Или добавить оператор после второго метода? Или переименовать метод?

1 Ответ

0 голосов
/ 09 апреля 2020

Может ли MyMeta генерировать код в MyClass, который перехватывает получение и установку атрибутов экземпляра MyClass?

Да. Это можно сделать, внедрив в класс методы __getattribute__ и __setattr__. Но если атрибуты объявлены в какой-либо другой форме (например, с аннотациями), он также может создавать дескрипторы для каждого атрибута для обработки только изменений этих атрибутов. Тем не менее, он не может легко догадаться, что представляют собой отдельные «атрибуты экземпляра», если они просто определены в классе c или установлены в коде внутри класса __init__ (но первый подход в любом случае охватывает все атрибуты). );

Может ли метод MyMeta вызываться при наследовании MyClass, даже если метакласс подкласса не является MyMeta?

Подкласс автоматически наследует MyMeta как свои метаклассы. Если существует конфликт из-за других баз, при использовании множественного наследования, имеющего другие метаклассы, подкласс не может быть создан вообще. (Если только один не создает подходящий метакласс, который наследует от обоих метаклассов, то есть). _TL; DR: да. и нет, нет подкласса с метаклассом, отличным от родительского.

Может ли метод MyMeta вызываться, когда метод MyClass переопределяется в подклассе, даже если метакласс подкласса не является MyMeta ?

Нет такой вещи, как "метакласс подкласса, не являющийся MyMeta". И затем метакласс воздействует на создание подкласса и может обнаруживать переопределения методов. И это может быть сделано даже для обнаружения переопределений методов путем установки обезьяны после создания класса (с помощью реализации метакласса __setattr__)

Может ли метод MyMeta вызываться, когда метод MyClass использует атрибут, который не был объявлен?

Да, устанавливая подходящие методы __getattribute__ и __setattr__, как указано ранее. Для этого не существует готовой функциональности (и метакласса также не требуется, просто будет работать миксин, реализующий оба метода)

Может ли MyMeta обрабатывать AST MyClass или другое эквивалентное представление? Например, может ли MyMeta проверить, содержит ли каждый метод класса не более 20 операторов? Или добавить оператор после второго метода? Или переименовать метод?

Метакласс называется способом после того, как AST был создан и преобразован в байт-код. Но он может проанализировать байт-код методов, чтобы проверить все, что захочет, и может извлечь их исходный код (если имеется) и заново сгенерировать AST, а также может воссоздать другие методы для замены исходных - заменители, имеющие все новый байт-код. Такие вещи, однако, редко, если вообще используются, звучат как излишнее.

Более подход Pythoni c будет состоять в том, чтобы использовать декораторы и использовать метакласс для автоматического применения декораторов к методам. Эти декораторы могут предоставлять функции-оболочки для запуска преамбулы и кода после вызова для каждого из методов, если это необходимо.

...