Metaclass
Метакласи⚑
Метакласи⚑
Summary
Метаклас - клас, який створює класи і визначає поведінку класів. Вони дозволяють контролювати процес створення класу, модифікувати його атрибути, методи та поведінку.
Метакласи працюють шляхом перехоплення створення класу на момент його визначення. При визначенні класу інтерпретатор Python шукає метаклас у його базових класах і, якщо знаходить, використовує його для створення нового класу.
Один з основних способів використання метакласів полягає в реалізації паттерну проектування "Одинак" (Singleton), де метаклас може гарантувати, що від класу може бути створений лише один екземпляр. Метакласи також використовуються в фреймворках, таких як Django і SQLAlchemy, для створення моделей бази даних.
Для створення метакласу використовується спеціальний метод __metaclass__
в класі. Цей метод визначає поведінку метакласу і виконується при створенні класу.
Створення класу з автоматичною реєстрацією у системі
class Registry(type):
def __init__(cls, name, bases, attrs):
super().__init__(name, bases, attrs)
register(cls)
class MyClass(metaclass=Registry):
pass
Links
Що таке type
. Як працює пошук метакласу при створенні об'єкта⚑
Три прояви type
- метаклас всіх класів. А самі класи можна вважати розширенням простих об'єктів - type(a)
- повертає тип об'єкту - type(name, bases, attrs)
- виклик конструктора класу
type
- це метаклас, який Python внутрішньо використовує для створення всіх класів. Отже, при замовчування, батьком буде object
, а метакласом - type
.
При написанні коду
Python робить наступне: - Чи має клас Foo атрибут __metaclass__
? - Якщо так, то створює в пам'яті об'єкт-клас з іменем Foo
, використовуючи те, що вказано в __metaclass__
. - Якщо Python не знаходить __metaclass__
, він шукає __metaclass__
у батьківському класі Bar
і спробує зробити те саме. - Якщо __metaclass__
не знаходиться ні в одному з батьків, Python буде шукати __metaclass__
на рівні модуля. - І якщо він зовсім не може знайти жодного __metaclass__
, він використовує type
для створення об'єкта-класу.
Навіщо використовувати метакласи⚑
Основне застосування метакласів - це створення фреймфорків. Типовий приклад - Django ORM.
class Person(models.Model):
name = models.CharField(max_length=30)
age = models.IntegerField()
guy = Person(name='bob', age='35')
print(guy.age)
age
- не IntegerField
, а int
, при цьому значення може бути отримано прямо з бази даних.
Це можливо, оскільки models.Model
визначає __metaclass__
, який здійснює деяку магію і перетворює клас Person
, який визначений простим виразом, на складне зв'язування з базою даних.
Django робить щось складне, що виглядає простим, надаючи просте API та використовуючи метакласи, які відтворюють код з API і непомітно виконують усю роботу.