Метакласс type в Python — параметры и примеры

В этом уроке вы узнаете о классе type в Python и поймете, как Python использует его для создания других классов.

Введение в класс type в Python

В Python класс — это объект класса type. Например, следующее определяет класс Person с двумя методами __init__ и Greeting:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def greeting(self):
        return f'Hi, I am {self.name}. I am {self.age} year old.'

Класс Person — это объект класса type, как показано в следующем примере:

print(type(Person))

Выход:

<class 'type'>

Класс Person является экземпляром класса type:

print(isinstance(Person, type))

Python использует данный класс для создания других классов. Сам класс type является вызываемым. Ниже показан один из конструкторов класса type:

type(name, bases, dict) -> a new type

Конструктор имеет три параметра для создания нового класса:

  • name: имя класса, например Person;
  • bases — это кортеж, содержащий базовые классы нового класса. Например, Person наследует от класса объекта, поэтому в базе содержится один класс(объект);
  • dict — это пространство имен класса.

Технически вы можете использовать класс type для динамического создания класса. Прежде чем делать это, вам необходимо понять, как Python создает классы.

Когда интерпретатор Python встречает в коде определение класса, он:

  • Сначала извлекает тело класса в виде строки.
  • Во-вторых, создает словарь классов для пространства имен классов.
  • В-третьих, выполняет тело класса, чтобы заполнить словарь классов.
  • Наконец, создает новый экземпляр типа, используя указанный выше конструктор type().

Давайте эмулируем описанные выше шаги, чтобы динамически создать класс Person:

Сначала извлеките тело класса:

class_body = """
def __init__(self, name, age):
    self.name = name
    self.age = age

def greeting(self):
    return f'Hi, I am {self.name}. I am {self.age} year old.'
"""

Во-вторых, создайте словарь классов:

class_dict = {}

В-третьих, выполните тело класса и заполните словарь классов:

exec(class_body, globals(), class_dict)

Функция exec() выполняет тело класса и заполняет глобальное пространство имен и пространство имен классов.

Наконец, создайте новый класс Person, используя конструктор type:

Person = type('Person',(object,), class_dict)

Обратите внимание, что Person — это класс, который также является объектом. Класс Person наследует класс объекта и имеет пространство имен class_dict.

Ниже показан тип класса Person, который является классом type:

<class 'type'>

И это экземпляр класса type:

print(isinstance(Person, type))

Выход:

True

class_dict имеет две функции __init__ и Greeting:

{'__init__': <function __init__ at 0x0000024E28465160>,
 'greeting': <function greeting at 0x0000024E28931550>}

Person.__dict__ также содержит следующие функции:

mappingproxy({'__dict__': <attribute '__dict__' of 'Person' objects>,
              '__doc__': None,
              '__init__': <function __init__ at 0x00000165F7725160>,
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'Person' objects>,
              'greeting': <function greeting at 0x00000165F7F71550>})

В этом примере Python динамически создает класс type, который совпадает с тем, который вы определяете статически в коде.

Поскольку класс type создает другие классы, мы часто называем его метаклассом. Метакласс — это класс, используемый для создания других классов.

Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *