Как создаются классы Python
Разберитесь в type, метаклассе по умолчанию и хуках создания классов.
«Как создаются классы Python» — бесплатный урок Python Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.
type() — метакласс
Каждый класс в Python является экземпляром type. Сам type является классом — это метакласс всех метаклассов.
# These are equivalent:
class Dog:
sound = "woof"
Dog2 = type("Dog2", (), {"sound": "woof"})
print(type(Dog)) # <class 'type'>
print(type(Dog2)) # <class 'type'>Трёхаргументная форма type()
type(name, bases, namespace) динамически создаёт новый класс. Именно это инструкции class делают внутри.
Animal = type("Animal", (), {"speak": lambda self: "..."})
Dog = type("Dog", (Animal,), {"speak": lambda self: "woof"})
d = Dog()
print(d.speak()) # woofЭтапы создания класса
Когда Python встречает инструкцию class, он: 1) определяет метакласс, 2) подготавливает пространство имён, 3) выполняет тело класса, 4) вызывает metaclass(name, bases, namespace).
# class Foo(Base, metaclass=Meta):
# x = 1
#
# Equivalent to:
# namespace = Meta.__prepare__("Foo", (Base,))
# exec(class_body, namespace)
# Foo = Meta("Foo", (Base,), namespace)__prepare__
__prepare__(name, bases, **kw) — это метод класса метакласса, возвращающий словарь пространства имён, используемый при выполнении тела класса. Переопределите его, чтобы использовать OrderedDict или специальное отображение.
class OrderedMeta(type):
@classmethod
def __prepare__(mcs, name, bases, **kw):
print(f"Preparing namespace for {name}")
return {}
class MyClass(metaclass=OrderedMeta):
x = 1
y = 2__new__ и __init__ в type
type.__new__ создаёт объект класса, а type.__init__ инициализирует его. В метаклассах переопределяйте __new__, чтобы настраивать создание классов.
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kw):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kw)
return cls._instances[cls]
class DB(metaclass=Singleton):
pass
print(DB() is DB()) # TrueДекораторы классов и метаклассы
Декораторы классов применяются после создания, а метаклассы управляют самим созданием. Для простого расширения предпочитайте декораторы. Используйте метаклассы, когда необходимо влиять на процесс создания.
def add_repr(cls):
cls.__repr__ = lambda self: f"{cls.__name__}()"
return cls
@add_repr
class Widget:
pass
print(Widget()) # Widget()__init_subclass__
__init_subclass__ вызывается у базового класса всякий раз, когда определяется подкласс. Это облегчённая альтернатива метаклассам для настройки поведения подклассов.
class Plugin:
_registry = []
def __init_subclass__(cls, **kw):
super().__init_subclass__(**kw)
Plugin._registry.append(cls)
class AudioPlugin(Plugin): pass
class VideoPlugin(Plugin): pass
print(Plugin._registry) # [AudioPlugin, VideoPlugin]ABCMeta
ABCMeta — встроенный метакласс, обеспечивающий работу абстрактных базовых классов с помощью @abstractmethod.
from abc import ABCMeta, abstractmethod
class Shape(metaclass=ABCMeta):
@abstractmethod
def area(self): ...
class Circle(Shape):
def __init__(self, r): self.r = r
def area(self): return 3.14159 * self.r ** 2
# Shape() # TypeError: Can't instantiate abstract classПроверка метакласса класса
Используйте type(cls), чтобы узнать метакласс класса, а cls.__mro__ — чтобы просмотреть порядок разрешения методов.
class Meta(type): pass
class Foo(metaclass=Meta): pass
print(type(Foo)) # <class '__main__.Meta'>
print(Foo.__mro__) # (Foo, object)Наследование метаклассов
Подклассы наследуют метакласс класса. Если у двух базовых классов разные метаклассы, необходимо использовать наиболее производный из них (иначе возникает конфликт).
class MyMeta(type): pass
class Base(metaclass=MyMeta): pass
class Child(Base): pass # Child's metaclass is also MyMeta
print(type(Child)) # <class '__main__.MyMeta'>Когда использовать метаклассы
Используйте метаклассы для автоматической регистрации подклассов, обеспечения инвариантов класса, обнаружения полей ORM (например, у Model в Django) и маршрутизации в рамках API. В большинстве случаев вместо этого используйте __init_subclass__ или декораторы классов.
# Real-world: Django ORM uses ModelBase metaclass
# to collect field definitions into _meta
# You rarely need a custom metaclass;
# __init_subclass__ covers most plugin/registration patternsБыстрая проверка
Что делает type("Dog", (Animal,), {"speak": lambda self: "woof"})?
Итоги
Каждый класс является экземпляром type. Конвейер создания класса: определить метакласс → подготовить пространство имён → выполнить тело → вызвать метакласс. Для простых обработчиков подклассов предпочитайте __init_subclass__, а полноценный метакласс используйте только при необходимости управлять самим созданием класса.
Часто задаваемые вопросы
Урок «Как создаются классы Python» бесплатный?
Да — полный текст урока «Как создаются классы Python» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.
Чему я научусь в уроке «Как создаются классы Python»?
Разберитесь в type, метаклассе по умолчанию и хуках создания классов. Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Python Academy?
Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Как создаются классы Python»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Python Academy?
Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Как создаются классы Python
- Написание пользовательских метаклассов
- Дескрипторы: __get__, __set__, __delete__
- __slots__ и оптимизация памяти