Mypy (и PEP 484 в целом) спроектированы таким образом, что в наиболее идеальном случае вам нужно только добавлять аннотации типов к «границам» или «интерфейсам» вашего кода.
Например, в основном вы должны добавить аннотации / метаданные типа в следующих местах:
- Параметр и возвращаемый тип функций и методов.
- Любые поля объекта (при условии, что типы ваших полей не являются простыми, просто взглянув на конструктор)
- Когда вы наследуете класс. Например, если вы специально хотите подклассицировать вклада от int до strs, вы должны сделать
class MyClass(Dict[int, str]): ...
, а не class MyClass(dict): ...
.
Это все примеры «границ» вашего кода. Подсказки типов для типов параметров / возвращаемых данных позволяют вызывающей стороне функции удостовериться, что они вызывают ее правильно, подсказки типа в полях позволяют вызывающей стороне знать, что они правильно используют объект и т. Д.
Mypy (и другие совместимые с PEP 484 инструменты) будут затем использовать эту информацию и попытаться вывести типы всего остального. Это поведение предназначено для имитации того, как люди читают код: например, когда вы знаете, какие типы передаются, например, довольно легко понять, что делает остальная часть кода.
В конце концов, Python - это язык, который с самого начала разрабатывался как читабельный! Нам не нужно разбрасывать подсказки типов везде, чтобы улучшить наше понимание того, что делает код.
Конечно, mypy (и другие PEP 484-совместимые инструменты) не идеальны, и иногда они могут неправильно определять тип какой-либо локальной переменной. В этом случае вам может понадобиться добавить подсказку типа, чтобы помочь mypy. Ответ Итана дает хороший обзор некоторых распространенных случаев, на которые стоит обратить внимание. (Интересно, что эти случаи также являются примерами того, как читатель человек может изо всех сил пытаться понять ваш код!)
Итак, чтобы собрать все воедино, общая рекомендация:
- Добавьте подсказки типов ко всем «границам» вашего кода, таким как параметры функций и типы возвращаемых данных.
- По умолчанию не аннотирующие переменные. Если mypy не может определить тип переменной, добавьте аннотацию, чтобы помочь ей.
- Если вам нужно аннотировать множество переменных, чтобы сделать mypy счастливым, рассмотрите возможность рефакторинга вашего кода. Если mypy легко запутать, читатель-человек также может легко запутаться.
Итак, чтобы вернуться к своим примерам, вы бы не добавили подсказки типа в любом случае. Как читатель, так и mypy могут сказать, что ваше поле _volume
должно быть числом с плавающей точкой: это очевидно, так должно быть, поскольку параметр является числом с плавающей точкой, а умножение числа с плавающей точкой на целое всегда будет вызывать другое значение с плавающей точкой.
Аналогично, вы бы не добавили аннотацию к вашей переменной my_volume
. Так как return_volume()
имеет подсказки типов, легко увидеть, какой тип он возвращает, и понять, что my_volume
имеет тип float. (И если вы допустили ошибку и случайно подумали, что это нечто иное, чем поплавок, mypy поймет это за вас.)