Подсказки типов и статическая типизация
Аннотируйте код так, чтобы проверяющий инструмент находил целые классы ошибок ещё до запуска
mypy, читает эти подсказки и сообщает о несоответствиях не запуская вашу программу. Вы сохраняете гибкость Python и получаете защитную сеть уровня компилятора, которая масштабируется на большие проекты.
- писать аннотации функций и переменных современным синтаксисом 3.11+ (
list[int],X | None), - выбирать нужный инструмент из модуля
typing(Optional,Callable,Literal,TypedDict,Protocol...), - запускать
mypyи читать его ошибки, - писать обобщённый код с
TypeVarи структурные интерфейсы сProtocol, - честно объяснять компромиссы постепенной типизации и то, где подсказки перестают помогать.
1. Подсказка — это метаданные, а не проверка при выполнении
Самый важный факт о подсказках типов: CPython их не проверяет. Аннотация хранится как метаданные и в остальном игнорируется во время работы программы. Ничто не вызовет исключение только потому, что реальное значение не совпадает с подсказкой.
def double(n: int) -> int:
return n * 2
print(double("ab")) # работает: печатает abab
print(double.__annotations__)
# {'n': <class 'int'>, 'return': <class 'int'>}
Передача str туда, где подсказка говорит int, не вызывает ошибку; "ab" * 2 — корректный Python, поэтому печатается abab. Подсказка носит рекомендательный характер. Она приносит пользу только когда статический анализатор читает её перед запуском кода и говорит: «строка 4 передаёт str в параметр типа int». Это разделение — аннотации во время написания, проверка как отдельный шаг, обычное динамическое поведение при выполнении — и есть вся модель. Аннотации живут в __annotations__ и потребляются инструментами (mypy, pyright, IDE, pydantic, dataclasses), а не самим интерпретатором.