Рубрики
Без рубрики

Метакласс в Питоне

Метакласс – это класс класса. Всякий раз, когда создается экземпляр класса (объекта), как ведет себя объект, определяется классом. Метакласс

Автор оригинала: Pankaj Kumar.

Метакласс в Питоне

А Метакласс это класс класса. Всякий раз, когда создается экземпляр класса (объекта), как ведет себя объект, определяется классом. Метакласс определяет поведение самого класса.

Использование метакласса в Python

Причина использования метаклассов состоит в том, что классы Python являются самими объектами. Поскольку классы – это объекты, мы можем сделать различные операции на нем, например, назначение его переменной, копирования и т. Д.

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

Чтобы лучше понять концепцию метакласс, мы сначала посмотрим, как Python определяет классы. Язык определяет все как объект, будь то int , а строка или что-нибудь еще.

Чтобы посмотреть на тип любого объекта Python, если вы помните, мы используем Тип функция.

>>> print(type(123))

>>> print(type([1, 2, 3]))


>>> class A():
...     def __init__(self):
...             pass
...
>>> a = A()
>>> print(type(a))

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

>>> print(type(type(123))

>>> print(type(A))

Как видите, тип ( класс ) – это класс Тип ! Так оказывается, что класс определяется самим классом? Что это за феномен?

Это концепция метакласса, которая служит для определения других классов. В основном это классовое завод, из которого другие классы, такие как int S и ул ...| s можно определить.

Метакласс

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

И потому что Тип Это метакласс, мы можем создать другие классы от него.

Создание классов динамично

Мы можем динамически создавать классы по экземпляру от конструктора типа: Тип (имя, базы, ATTR)

  • Имя -> Название класса
  • Основы -> классы, из которых новый класс наследуется от
  • attr -> Словарь атрибутов + методы, содержащиеся в классе
>>> Animal = type('Animal', (), dict(__init__ = lambda self: None, worth = lambda self, value: value))

Это так же, как:

class Animal():
    def __init__(self):
        pass
    
    def worth(self, value):
        return value

Первый бит кода гораздо проще написать по сравнению со вторым. Написание классового тела даже во время динамической декларации не обеспечивает большой гибкости.

Следовательно, метаклассы обеспечивают мощный и простой способ динамически создания новых классов.

Создание пользовательских метакласс

Чтобы создать наш собственный метакласс, нам нужно унаследовать существующий «тип метакласс» и переопределить некоторые специальные методы:

  • __ Новый __ () -> Это называется до __init __ () Отказ Он отвечает за создание объекта и возвращает его.
  • __ init __ () -> Это предназначено для инициализации вновь созданного объекта, который передается как параметр (Parameter Self )

Следующий фрагмент показывает, как может быть создан метакласс:

class MyMetaclass(type):
    def __new__(cls, name, bases, dict):
        print('Creating a new object of', name)
        # Invoke __new__() method of the metaclass type
        return super(MyMetaclass, cls).__new__(cls, name, bases, dict)

    def __init__(cls, name, bases, dict):
        print('Initialising class', name)
        super(MyMetaclass, cls).__init__(name, bases, dict)

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

Для этого мы передаем Метакласс Параметр в новом определении класса, который сообщает классу использовать наш пользовательский метакласс, так как это собственное метакласс, а не Тип Отказ

class Student(metaclass=MyMetaclass):
    def __init__(self, name):
        self.name = name

    def get_name(self):
        return self.name

Здесь Студент использует MyMetaclass как его метакласс. Поэтому при создании экземпляра студента наши пользовательские методы метаклассов будут называться вместо Тип метакласс.

stud = Student('Amit')
print(stud.get_name())
print('Type of Student object:', type(stud))
print('Type of Student Class:', type(Student))

Выход

Creating a new object of Student
Initialising class Student
Amit
Type of Student object: 
Type of Student Class: 

Примечание : Старые версии Python из 2.7 или ниже используют __metaclass__ Ключевое слово для указания используемого метакласса. Python3 изменил это поведение, чтобы пройти Метакласс как параметр.

Выводы

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

Эта статья служит только отправной точкой для темы, а о том, как понять, как Python определяет все с точки зрения Тип метакласс.

Мы посмотрели на то, как Metaclasses могут быть созданы, а методы, которые называются во время создания классов.

использованная литература

Packoverflow Post On MetaClasses (это обеспечивает глубокое обсуждение этой темы. Рекомендуется, если вы хотите узнать больше о метаклассах): https://stackoverflow.com/questions/100003/what-are-metaclasses-in-python.