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”