Что такое протоколы в модуле typing в Python
Что проверяют
Понимаете ли вы разницу между номинальной и структурной типизацией. Протокол описывает форму объекта, а не его происхождение, и вопрос проверяет, умеете ли вы типизировать утиную типизацию, к которой в Python всё равно всё сводится.
Как отвечать
Протокол это класс, унаследованный от Protocol, в котором перечислены нужные методы и атрибуты. Подходит любой объект такой же формы, наследоваться от протокола не требуется: совместимость проверяет анализатор типов по структуре.
from typing import Protocol
class SupportsClose(Protocol):
def close(self) -> None: ...
def shutdown(resource: SupportsClose) -> None:
resource.close()Зачем это нужно: типизировать чужие классы, которые нельзя править; объявить узкий интерфейс на стороне потребителя, а не тащить зависимость от реализации; спокойно подставлять заглушки в тестах.
Детали, которые отличают знающего: декоратор для проверок во время выполнения разрешает isinstance, но проверка смотрит только наличие атрибутов, не их типы и не сигнатуры, а issubclass с атрибутами-данными не работает вовсе. Изменяемый атрибут делает протокол инвариантным, только для чтения он описывается свойством. Есть протоколы для вызываемых объектов через __call__ и обобщённые протоколы с параметрами типа. Явное наследование допустимо и добавляет проверку, что класс действительно реализует форму.
Где спотыкаются
Ждут проверок во время выполнения. Сама аннотация не проверяет ничего, ошибку находит анализатор типов в сборке, а проверка экземпляра сверяет только имена атрибутов, так что объект с методом другой сигнатуры её пройдёт.
Описывают протокол по реализации, копируя весь публичный интерфейс класса. Смысл обратный: потребитель объявляет минимум, который ему нужен, и тогда подставить другую реализацию действительно легко.
Не видят разницы с абстрактным базовым классом. Тот требует наследования или регистрации и умеет нести реализацию, протокол не требует от чужого класса ничего. Выбор простой: свой код и общая база это абстрактный класс, чужой код и описание формы это протокол.