0Pricing
Python Academy · Урок

Как создаются классы 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 — локальная установка не требуется.

Все уроки этого курса

  1. Как создаются классы Python
  2. Написание пользовательских метаклассов
  3. Дескрипторы: __get__, __set__, __delete__
  4. __slots__ и оптимизация памяти
← Назад к Python Academy