Зачем использовать абстрактные базовые классы в Python?

Поскольку я привык к старым способам печатания утки в Python, я не понимаю необходимости ABC (абстрактные базовые классы). Справка хороша в том, как их использовать.

Я попытался прочитать обоснование в PEP , но это пошло мне на ум. Если бы я искал контейнер изменяемой последовательности, я бы проверил __ setitem __ , или, более вероятно, попытайтесь использовать его ( EAFP ). Я не сталкивался с реальным использованием модуля чисел , который использует азбуку, но это самое близкое, что я должен понять.

Может ли кто-нибудь объяснить мне обоснование, пожалуйста?

192
задан mc_kaiser 4 October 2018 в 06:34
поделиться

2 ответа

Краткая версия

ABC предлагает более высокий уровень семантического контракта между клиентами и реализованными классами.

Полная версия

Существует контракт между классом и его вызывающими объектами. Класс обещает делать определенные вещи и иметь определенные свойства.

Существуют различные уровни контракта.

На очень низком уровне контракт может включать имя метода или количество его параметров.

В языке со статической типизацией этот контракт фактически будет обеспечиваться компилятором. В Python вы можете использовать EAFP или самоанализ, чтобы подтвердить, что неизвестный объект соответствует этому ожидаемому контракту.

Но в договоре есть и семантические обещания более высокого уровня.

Например, если есть метод __str__(), ожидается, что он вернет строковое представление объекта. Он мог удалить все содержимое объекта, зафиксировать транзакцию и выплюнуть из принтера чистую страницу... но есть общее понимание того, что он должен делать, описанное в руководстве по Python.

Это особый случай, когда семантический контракт описан в руководстве. Что должен делать метод print()? Должен ли он записывать объект на принтер или строку на экран или что-то еще? Это зависит от вас - вам нужно прочитать комментарии, чтобы понять полный контракт здесь. Фрагмент клиентского кода, который просто проверяет существование метода print(), подтвердил часть контракта — что вызов метода может быть выполнен, но не существует соглашения о семантике вызова более высокого уровня. .

Определение абстрактного базового класса (ABC) — это способ создания контракта между реализаторами класса и вызывающими объектами. Это не просто список имен методов, а общее понимание того, что эти методы должны делать. Если вы наследуете эту ABC, вы обещаете следовать всем правилам, описанным в комментариях, включая семантику метода print().

Утиная типизация Python имеет много преимуществ в гибкости по сравнению со статической типизацией, но она не решает всех проблем. ABC предлагают промежуточное решение между свободной формой Python и кабалой и дисциплиной языка со статической типизацией.

144
ответ дан 23 November 2019 в 05:29
поделиться

Это значительно упростит определение того, поддерживает ли объект данный протокол, без проверки наличия всех методов в протоколе или без запуска исключения глубоко на «вражеской» территории из-за отсутствия поддержки.

17
ответ дан 23 November 2019 в 05:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: