Метакласс 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 создает другие классы, мы часто называем его метаклассом. Метакласс — это класс, используемый для создания других классов.