Продвинутый курс по Python

Углубленный курс для Python-разработчиков, охватывающий асинхронное программирование, метаклассы, тестирование и архитектуру. Программа составлена с учетом современных требований индустрии на основе материалов [ru.hexlet.io](https://ru.hexlet.io/courses/advanced_python) и [wiki.merionet.ru](https://wiki.merionet.ru/merion-academy/course/python-advanced-prodvinutyj-kurs).

1. Глубокое погружение в ООП: метаклассы, дескрипторы и паттерны проектирования

Глубокое погружение в ООП: метаклассы, дескрипторы и паттерны проектирования

Объектно-ориентированное программирование в Python скрывает под своим капотом мощные механизмы, позволяющие разработчикам вмешиваться в процессы создания классов и управления их атрибутами. Этот уровень абстракции часто называют метапрограммированием — написанием кода, который управляет другим кодом.

Понимание того, как язык обрабатывает объекты на глубинном уровне, позволяет строить гибкие, масштабируемые и безопасные архитектуры. Основными инструментами для этого выступают метаклассы и дескрипторы, которые органично вплетаются в классические паттерны проектирования.

Метаклассы: фабрики для классов

В Python абсолютно всё является объектом, включая сами классы. Если класс — это чертёж, по которому создаются экземпляры (объекты), то метакласс — это чертёж для создания самих классов. По умолчанию все классы в языке создаются с помощью встроенного метакласса type.

Процесс создания класса можно перехватить и изменить. Для этого необходимо создать собственный метакласс, унаследовав его от type, и переопределить магический метод __new__ или __init__.

Представьте корпоративную систему, в которой работает 50 различных классов для интеграции с внешними API. Если в каждый класс нужно добавить единый таймаут соединения, ручное редактирование потребует изменения 50 файлов. Использование метакласса позволяет внедрить значение таймаута, равное 120 секундам, на этапе компиляции кода. Если в будущем таймаут изменится на 60 секунд, правку потребуется внести ровно в одной строке метакласса.

Метаклассы решают следующие задачи: * Автоматическая регистрация классов в реестре (например, для плагинов). * Валидация атрибутов класса на этапе его объявления. * Динамическое добавление или изменение методов.

Дескрипторы: умное управление атрибутами

Если метаклассы управляют классами, то дескрипторы берут на себя контроль над доступом к атрибутам экземпляров.

> Дескриптор — это любой объект, который определяет магические методы __get__, __set__ или __delete__. Когда атрибутом класса является дескриптор, срабатывает особое поведение поиска атрибута. > > Официальный глоссарий Python

Дескрипторы лежат в основе многих привычных инструментов Python, таких как @property, @classmethod, @staticmethod и даже самих функций.

В этом примере дескриптор PositiveInteger гарантирует, что значения всегда будут строго положительными: .

Допустим, интернет-магазин обрабатывает 10 000 транзакций в минуту. Если из-за ошибки в логике цена товара (price) установится на уровне -500 руб., магазин начнёт терять деньги. Дескриптор перехватывает операцию присваивания на самом низком уровне. Попытка выполнить Product(-500, 10) моментально вызовет исключение ValueError, предотвращая создание некорректного объекта.

Паттерны проектирования через призму Python

Паттерны проектирования — это типовые решения часто встречающихся архитектурных проблем. Благодаря динамической типизации и метапрограммированию, многие классические паттерны реализуются в Python гораздо лаконичнее, чем в языках со строгой статической типизацией (например, Java или C++).

| Название паттерна | Классическая реализация | Реализация в Python | | :--- | :--- | :--- | | Одиночка (Singleton) | Скрытие конструктора, статический метод getInstance() | Использование метакласса или декоратора для контроля создания экземпляров | | Стратегия (Strategy) | Создание иерархии классов с общим интерфейсом | Передача функции как объекта первого класса (First-class citizen) | | Наблюдатель (Observer) | Интерфейсы Publisher и Subscriber с методами обновления | Использование встроенных механизмов событий или простых списков callback-функций |

Рассмотрим реализацию паттерна Одиночка (Singleton) с использованием метакласса. Этот паттерн гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа.

Математически логику Singleton можно описать так: для любого количества запросов на создание объекта , количество выделенной памяти всегда равно памяти для одного объекта. Если объект подключения к базе данных занимает 50 Мегабайт оперативной памяти, то при создании 100 таких объектов обычным способом приложение потребило бы 5000 Мегабайт (около 5 Гигабайт). Использование метакласса SingletonMeta гарантирует, что сколько бы раз разработчик ни вызывал DatabaseConnection(), в памяти останется ровно один объект размером 50 Мегабайт.

Метапрограммирование и глубокое понимание ООП превращают разработчика из пользователя языка в его архитектора. Умение грамотно применять метаклассы и дескрипторы позволяет создавать библиотеки и фреймворки, которые интуитивно понятны в использовании и надежно защищены от некорректных действий на уровне ядра.