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

Введение в Python Metaclasses

Metaclass Python являются важной, хотя и не всегда используемой функцией метапрограммирования. Это позволяет, я … Tagged with Python, учебник.

Metaclass Python являются важной, хотя и не всегда используемой функцией метапрограммирования. Это позволяет, среди прочего, динамически создавать классы. Поскольку вы можете создать метод объекта заводского производства, используя MetaClasses, вы можете определить фабрику класса.

Что такое Metaclass? По сути, это просто класс класса.

Классы являются объектами

Когда класс создан, создается объект:

>>> a = [1,2,3,4,5]
>>> type(a)

>>> 

Но когда класс Заявление встречается интерпретатором Python, он также создает объект типа тип :

>>> class A:
...     pass
... 
>>> type(A)

Итак, объекты, созданные из класса T типа T , но сами классы также являются объектами класса тип .

Будучи объектами, классы можно манипулировать непосредственно как любой объект Python:

# dummy classes
class A:
    """ comment for class A """
    pass


class B:
    """ comment for class B """
    pass


class C:
    """ comment for class C """
    pass

# classes are objects: we can store them into a list
list_of_classes = [A,B,C]

# type of classes are 'type'
for cls in list_of_classes:
    print(type(cls))
    print(cls.__doc__)

# we can define a function whose parameter is a class
def class_name(cls: type) -> str:
    return cls.__name__

# treat classes like objects
list_of_str_classes = [class_name(cls) for cls in list_of_classes]

# we get ['A', 'B', 'C']
print(list_of_str_classes)

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

Вы, вероятно, привыкли создавать экземпляры класса:

>>> a = A()
>>> type(a)

>>> b = list()
>>> type(b)

>>> 

Чтобы создать новый класс, нам нужно использовать Тип Класс с своеобразным синтаксисом.

Самый простой способ создания класса – это:

# create a simple class A dynamically. A is an instance of 'type'
A = type('A', (), {})
print(type(A))

# create an instance of A. a is of type A
a = A()
print(type(a))

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

# create a Person class with default values for its attributes
Person = type('Person', (), {
    'first_name': 'John',
    'last_name' : 'Doe',
    'get_name': lambda self: self.first_name + ' ' + self.last_name
})

# create a Person instance
person = Person()
print(person.get_name())

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

Metaclass – это способ настроить способ создания класса. Чтобы создать Metaclass, вам нужно подкласс Тип тип. Чтобы сделать класс экземпляром MetaClass, вы будете использовать выделенный синтаксис с Metaclass = Аргумент:

class MyMetaClass(type):
    """ a metaclass derives from the 'type' type """

    def __new__(cls, name, bases, dict):
        """ __new()__ is the class constructor """
        print(f"cls={cls}, name={name}, bases={bases}, dict={dict}")
        return super().__new__(cls, name, bases, dict)

class MyClass(metaclass=MyMetaClass):
    pass

a = MyClass()
print(type(a))

Из официальной документации Python:

Потенциальное использование для метатаксов безгранична. Некоторые идеи, которые были изучены, включают enum, ведение журнала, проверку интерфейса, автоматическое делегирование, автоматическое создание свойств, прокси, фреймворки и автоматическую блокировку/синхронизация ресурсов.

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

import pprint

class PrettyPrinterWrapper(type):
    def __new__(cls, name, bases, dict):
        """ define a new handler attribute a pretty printer instance """
        dict['pp'] = pprint.PrettyPrinter(width=20)

        return super().__new__(cls, name, bases, dict)

class A(metaclass=PrettyPrinterWrapper):
    def __init__(self, my_list: list):
        self.list = my_list

    def __str__(self):
        return self.pp.pformat(self.list)

a = A(["one","two","three","four"])
print(a)

Надеюсь это поможет !

Фото Алины Грубняк на Unsplash

Оригинал: “https://dev.to/dandyvica/introduction-to-python-metaclasses-887”