Python. Абстрактные базовые классы

Перевод параграфа 6.7 Abstract Base Classes из книги Intermediate Python.

Чтобы классы реализовывали заданный набор методов в статически типизированных языках, таких как Java, используются интерфейсы и абстрактные классы.

Простая реализация такого контракта в Python — добавить в базовый класс методы по умолчанию, выбрасывающие исключение NotImplementedError. Такое решение неполное: наследники могут не переопределить все методы базового класса, а проблема обнаружится только во время выполнения программы.

Рассмотрим другую ситуацию — использование одного объекта для замещения другого. Заместитель перехватывает все вызовы и передаёт их в скрываемый объект. Заместитель реализует все нужные методы, но проверку типа через isinstance он не проходит, так как имеет тип отличный от замещаемого объекта.

В Python такие задачи решаются через абстрактные базовые классы, реализуемые модулем abc. Этот модуль определяет мета-класс и набор декораторов. Для определения абстрактного базового класса мы устанавливаем ABCMeta как мета-класс абстрактного класса и помечаем декораторами @abstractmethod и @abstractproperty методы и свойства которые должны быть реализованы в неабстрактных потомках.

Если потомки не реализуют абстрактные методы и свойства то не смогут создавать объекты:

Как только класс реализовал все абстрактные методы появляется возможность создавать объекты:

Абстрактные классы позволяет регистрировать существующие классы как часть своей иерархии, не проводя проверок на реализацию методов и свойств. Это простое решение второй проблемы открывающей параграф. Абстрактный класс регистрирует класс заместитель и проверка isinstance возвращает корректное значение:

Абстрактные базовые классы широко используются в библиотеке Python. Они предоставляют средство для группировки классов, например, числовых типов, которые имеют относительно плоскую иерархию. Модуль collections также содержит абстрактные базовые классы для различных наборов операций с множествами, последовательностями и словарями. Абстрактные базовые классы Python предоставляют возможность применять контракты между классами такие же как интерфейсы в Java.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *