Цитата выше взята из PEP 544 (Python Enhancement Proposal, предложение о доработке), который был реализован в Python 3.8. Начиная с этой версии в питоне появились протоколы.
Протокол описывает поведение без реализации (в других языках такие штуки обычно называют интерфейсами). Вот наш Летающий Объект:
from typing import Protocol
class Flyer(Protocol):
def fly(self):
...
Мы используем протокол, чтобы указать, что объект должен обладать конкретным поведением. Наша функция умеет запускать только Летающие Объекты:
def launch(thing: Flyer):
thing.fly()
Причем самим объектам не надо знать о протоколе. Достаточно обладать нужным поведением:
class Frank:
def fly(self):
# ...
class Plane:
def fly(self):
# ...
class Superman:
def fly(self):
# ...
Протокол — это статическая утиная типизация:
— интерфейс явно описан в протоколе: летающий объект обладает методом
fly();— но реализуется он неявно, по «утиному» принципу: у Супермена есть метод
fly() — значит он летающий объект.Проверим:
$ mypy flyer.py
Success: no issues found in 1 source file
Идеально!