Ответ
Протоколы (typing.Protocol) в Python используются для определения интерфейсов на основе структурной типизации (также известной как 'утиная типизация'). Они позволяют статическим анализаторам типов (например, mypy, pyright) проверять, соответствует ли объект определенному набору методов и атрибутов, без необходимости явного наследования.
Основные сценарии использования Protocol:
-
Абстракция без наследования: Когда нужно определить интерфейс, но нет необходимости или возможности использовать абстрактные базовые классы (
abc.ABC) или явное наследование. Это идеально для случаев, когда классы уже существуют и реализуют нужные методы, но не имеют общего предка.from typing import Protocol class Drawable(Protocol): def draw(self) -> None: ... # Определение сигнатуры метода class Circle: def draw(self) -> None: print("Drawing a circle") class Square: def draw(self) -> None: print("Drawing a square") def render(obj: Drawable) -> None: obj.draw() render(Circle()) # Работает, так как Circle соответствует протоколу Drawable render(Square()) -
Обратная совместимость и интеграция: Для типизации объектов из сторонних библиотек или унаследованного кода, где вы не можете изменить иерархию наследования, но хотите обеспечить проверку типов.
-
Аннотация callback-функций: Для четкого описания ожидаемой сигнатуры функций, передаваемых в качестве аргументов.
from typing import Protocol class StringProcessor(Protocol): def __call__(self, data: str) -> int: ... def process_data(processor: StringProcessor, text: str) -> int: return processor(text) def my_processor(s: str) -> int: return len(s) print(process_data(my_processor, "hello")) # 5 -
Гибкость в дизайне: Позволяют создавать более гибкие и слабосвязанные системы, где компоненты взаимодействуют через их поведение, а не через их иерархию классов.
Протоколы особенно полезны в сочетании с декоратором @runtime_checkable (из typing), который позволяет проверять соответствие протоколу во время выполнения с помощью isinstance() и issubclass(), что расширяет их применение за пределы статической проверки типов.