/
Блог Хекслета
/
Код
/

ООП в Python: классы, метаклассы, MRO и магические методы

ООП в Python: классы, метаклассы, MRO и магические методы

10 марта 2026 г.
6 минут
ООП в Python: классы, метаклассы, MRO и магические методы

Объектно-ориентированное программирование в Python — не только синтаксис class и наследование, но и то, как интерпретатор создаёт классы, как ищет атрибуты (MRO), как работают метаклассы, дескрипторы и магические методы. В материале — сжатый разбор этих тем с опорой на экспертный ролик: в нём Никита Соболев (core-разработчик CPython и open-source) разбирает устройство ООП «изнутри». Видео можно посмотреть прямо в статье; в конце — ссылка на бесплатный курс по основам Python от Хекслета, чтобы закрепить базу и перейти к продвинутым темам.

Экспертный выпуск: ООП в Python изнутри

В этом выпуске разбираемся, как в Python устроены классы и объекты: от инструкций виртуальной машины до метаклассов и доступа к атрибутам. Спикер — Никита Соболев, core-разработчик CPython и других open-source проектов.

В видео вы узнаете:

  • что в Python классы можно создавать не только через наследование, но и от любых объектов;
  • почему понимание метаклассов важно для глубокого понимания ООП;
  • как расширять и модифицировать классы с помощью метаклассов;
  • про MRO, Name Mangling, магические методы и многое другое.

Видео: как работают классы в Python, метаклассы, MRO, дескрипторы, магические методы

Содержание

Как работают классы в Python

В Python класс — это объект. Когда вы пишете class Foo: ..., интерпретатор выполняет тело класса в отдельном namespace, а затем вызывает метакласс (по умолчанию type), чтобы создать объект класса. Этот объект потом используется как фабрика экземпляров: вызов Foo() создаёт экземпляр.

Важно: классы в Python можно создавать не только наследуя от других классов, но и от других объектов (например, от экземпляра). Такой механизм опирается на то, что класс — объект первого класса, и на работу метаклассов.

Класс создаётся метаклассом, экземпляр — классом Класс в Python — тоже объект метакласс (type) класс (Foo) экземпляр Foo() Метакласс создаёт класс; класс создаёт экземпляр

Рис. 1 — Цепочка: метакласс → класс → экземпляр

type и создание классов

Встроенная функция type в Python выполняет две роли:

  1. type(obj) — возвращает тип объекта (класс объекта).
  2. type(name, bases, dict) — создаёт новый класс: имя, кортеж базовых классов и словарь атрибутов (тело класса).

По сути объявление class Foo(Base): ... эквивалентно вызову метакласса (по умолчанию type) с соответствующими аргументами. Понимание этого помогает разобраться с метаклассами: кастомный метакласс — это то, что вызывается вместо type при создании класса.

Method Resolution Order (MRO)

MRO (Method Resolution Order) — порядок, в котором Python ищет атрибуты и методы при наследовании. Он строится по алгоритму C3 (линеаризация), так что порядок предков однозначный и предсказуемый. Посмотреть MRO класса можно так: ClassName.__mro__ или ClassName.mro().

От MRO зависит, какой метод будет вызван при obj.method() при нескольких предках с одинаковым именем метода. Понимание MRO необходимо для корректного использования super() и множественного наследования.

Метаклассы и конфликты

Метакласс — класс, экземпляры которого являются классами. То есть метакласс создаёт класс так же, как класс создаёт экземпляр. По умолчанию метакласс — type. Свой метакласс задаётся через class Foo(metaclass=MyMeta): ... или через наследование (если базовый класс уже использует кастомный метакласс).

Метаклассы позволяют модифицировать и расширять создание класса: проверять/изменять атрибуты, регистрировать классы, генерировать код и т.п. Понимание метаклассов действительно критично для глубокого понимания ООП в Python: без них непонятно, «кто» и «как» создаёт объект класса.

Конфликт метаклассов возникает, когда при множественном наследовании у базовых классов разные метаклассы. Python требует, чтобы один из метаклассов был подклассом другого; иначе будет ошибка.

Метакласс вызывается при создании класса Метаклассы Метакласс (наследник type) вызывается при выполнении class ...: можно изменить атрибуты, базы, имя Класс — экземпляр метакласса class Foo(metaclass=MyMeta): конфликт, если у баз разные метаклассы

Рис. 2 — Метакласс и создание класса

Наследование и доступ к атрибутам

При обращении к атрибуту через точку (obj.attr) Python не просто смотрит в obj.__dict__. Задействована цепочка: поиск в экземпляре, затем по классу и по MRO по всем базовым классам, а также механизм дескрипторов (если атрибут класса — дескриптор, вызываются его методы __get__ / __set__).

Внутри CPython за это отвечает, в частности, _PyObject_Generic_AttrWithDict. Понимание того, как ищется атрибут, объясняет поведение свойств (property), методов, слотов и кастомных дескрипторов.

Дескрипторы

Дескриптор — объект с методами __get__, __set__ и/или __delete__, определёнными в классе. Когда атрибут класса — дескриптор, при обращении к атрибуту экземпляра (чтение, запись, удаление) вызываются эти методы дескриптора. Так реализованы property, staticmethod, classmethod, слоты и многое другое. Дескрипторы — ключ к пониманию того, «как работают точки» при доступе к атрибутам.

Магические методы

Магические методы (dunder-методы, от double underscore) — методы с именами вида __имя__. Они вызываются интерпретатором в определённых ситуациях: __init__ — при создании объекта, __add__ — при сложении, __getitem__ — при индексации и т.д. Их переопределение позволяет задать поведение объектов в операциях и встроенных функциях.

На уровне C API различают, например, nb_add и sq_concat — сложение чисел и конкатенация последовательностей обрабатываются по-разному. Для повседневного кода достаточно знать основные магические методы и переопределять их при необходимости.

Примеры магических методов Магические методы (примеры) __init__ __add__ __getitem__ __str__ __len__ Вызываются интерпретатором при операциях и встроенных функциях

Рис. 3 — Примеры магических методов

Name Mangling и «приватные» атрибуты

В Python нет по-настоящему приватных атрибутов. Имена, начинающиеся с двух подчёркиваний и не заканчивающиеся двумя подчёркиваниями (например, __private), на этапе компиляции переписываются в форму _ClassName__private — это name mangling. Так уменьшаются шансы случайного пересечения имён в подклассах; «приватность» остаётся соглашением, доступ по _ClassName__private по-прежнему возможен.

super() и тонкости вызова

super() возвращает прокси-объект, который делегирует вызов метода следующему классу в MRO (относительно того класса, в контексте которого вызван super()). Важно: порядок определяется не только тем, от кого наследуется класс, но и тем, в каком классе находится текущий метод. При множественном наследовании неправильное использование super() приводит к пропуску или двойному вызову методов.

Резюме и что смотреть дальше

Кратко по материалу видео:

  • Класс в Python — объект, создаётся метаклассом (по умолчанию type).
  • MRO задаёт порядок поиска атрибутов при наследовании.
  • Метаклассы позволяют перехватывать и менять создание класса.
  • Доступ к атрибутам идёт через цепочку экземпляр → класс → MRO и дескрипторы.
  • Дескрипторы лежат в основе property, staticmethod, classmethod.
  • Магические методы задают поведение объектов в операциях.
  • Name mangling переименовывает «приватные» атрибуты вида __name.
  • super() делегирует вызов следующему в MRO с учётом текущего класса.

Чтобы уверенно переходить к таким темам, нужна база: синтаксис, типы данных, функции, базовое ООП (классы, наследование, методы). Ниже — ссылка на бесплатный курс, с которого удобно начать.

Выводы

  • В Python класс — объект; он создаётся метаклассом (по умолчанию type). Классы можно создавать и от других объектов, не только от классов.
  • MRO задаёт порядок поиска атрибутов при наследовании; с ним тесно связан вызов super().
  • Метаклассы перехватывают создание класса и позволяют его модифицировать; при множественном наследовании возможны конфликты метаклассов.
  • Доступ к атрибутам (через точку) идёт по цепочке экземпляр → класс → MRO и через дескрипторы (property, методы и т.д.).
  • Магические методы (__init__, __add__ и др.) определяют поведение объектов в операциях.
  • Name mangling переименовывает атрибуты вида __name в _ClassName__name; настоящей приватности в Python нет.

Начните с основ: бесплатный курс Python от Хекслета

Разбор ООП «изнутри» имеет смысл после того, как вы уверенно пишете классы, создаёте экземпляры и используете наследование в повседневном коде. Если вы только начинаете или хотите систематически закрепить основы Python, имеет смысл пройти структурированный курс.

Бесплатный курс «Основы Python» от Хекслета даёт именно такую базу: синтаксис, типы данных, строки, условия, циклы, функции и введение в ООП. В курсе 73 урока, 71 практическое упражнение в тренажёре и поддержка ИИ-ассистента для подсказок и разбора кода. После него будет проще воспринимать темы вроде метаклассов и MRO — как в нашем экспертом ролике выше.

Основы Python — бесплатно

57 часов, 73 урока, 71 упражнение. Синтаксис, типы данных, функции и основы ООП. Подходит для новичков.

Перейти на курс →

Удачи в изучении Python и ООП.

Никита Вихров

2 часа назад

0

Категории