Тип подсказки: когда нужно комментировать - PullRequest
0 голосов
/ 06 июля 2018

Я использую подсказки типа и mypy все больше и больше. У меня, однако, есть несколько вопросов о том, когда я должен явно аннотировать объявление, и когда тип может быть автоматически определен mypy.

Ex:

def assign_volume(self, volume: float) -> None:
    self._volume = volume * 1000

Должен ли я написать

self._volume: float = volume *1000

В этом случае?

Теперь, если у меня есть следующая функция:

def return_volume(self) -> float:
        return self._volume

и где-то в моем коде:

my_volume = return_volume()

Должен ли я написать:

my_volume: float = return_volume()

Ответы [ 3 ]

0 голосов
/ 06 июля 2018

Mypy делает довольно сложный вывод типа.Обычно вам не нужно аннотировать переменные.В документации mypy [1] говорится об этом:

Mypy рассматривает начальное присваивание как определение переменной.Если вы не укажете явно тип переменной, mypy выведет тип на основе статического типа выражения значения

. Общее правило тогда заключается в том, что «аннотируйте переменные, типы которых не являются выводимыми приих начальное назначение ".

Вот несколько примеров:

  • Пустые контейнеры.Если я определю a как a = [], mypy не будет знать, какие типы допустимы в списке a.

  • Optional типов.Часто, если я определяю тип Optional, я назначаю переменную None.Например, если я сделаю a = None, mypy выведет, что a имеет тип NoneType, если позже вы хотите назначить a на 5, вам нужно аннотировать его: a: Optional[int] = None.

  • Сложные вложенные контейнеры.Например, если у вас есть словарь со списком и строковыми значениями, mypy может, например, вывести Dict[str, Any].Возможно, вам понадобится аннотировать его, чтобы быть более точным.

Конечно, есть еще много случаев.

В ваших примерах mypy может вывести типы выражений.

[1] https://mypy.readthedocs.io/en/latest/type_inference_and_annotations.html

0 голосов
/ 06 июля 2018

Mypy (и PEP 484 в целом) спроектированы таким образом, что в наиболее идеальном случае вам нужно только добавлять аннотации типов к «границам» или «интерфейсам» вашего кода.

Например, в основном вы должны добавить аннотации / метаданные типа в следующих местах:

  1. Параметр и возвращаемый тип функций и методов.
  2. Любые поля объекта (при условии, что типы ваших полей не являются простыми, просто взглянув на конструктор)
  3. Когда вы наследуете класс. Например, если вы специально хотите подклассицировать вклада от int до strs, вы должны сделать class MyClass(Dict[int, str]): ..., а не class MyClass(dict): ....

Это все примеры «границ» вашего кода. Подсказки типов для типов параметров / возвращаемых данных позволяют вызывающей стороне функции удостовериться, что они вызывают ее правильно, подсказки типа в полях позволяют вызывающей стороне знать, что они правильно используют объект и т. Д.

Mypy (и другие совместимые с PEP 484 инструменты) будут затем использовать эту информацию и попытаться вывести типы всего остального. Это поведение предназначено для имитации того, как люди читают код: например, когда вы знаете, какие типы передаются, например, довольно легко понять, что делает остальная часть кода.

В конце концов, Python - это язык, который с самого начала разрабатывался как читабельный! Нам не нужно разбрасывать подсказки типов везде, чтобы улучшить наше понимание того, что делает код.

Конечно, mypy (и другие PEP 484-совместимые инструменты) не идеальны, и иногда они могут неправильно определять тип какой-либо локальной переменной. В этом случае вам может понадобиться добавить подсказку типа, чтобы помочь mypy. Ответ Итана дает хороший обзор некоторых распространенных случаев, на которые стоит обратить внимание. (Интересно, что эти случаи также являются примерами того, как читатель человек может изо всех сил пытаться понять ваш код!)

Итак, чтобы собрать все воедино, общая рекомендация:

  1. Добавьте подсказки типов ко всем «границам» вашего кода, таким как параметры функций и типы возвращаемых данных.
  2. По умолчанию не аннотирующие переменные. Если mypy не может определить тип переменной, добавьте аннотацию, чтобы помочь ей.
  3. Если вам нужно аннотировать множество переменных, чтобы сделать mypy счастливым, рассмотрите возможность рефакторинга вашего кода. Если mypy легко запутать, читатель-человек также может легко запутаться.

Итак, чтобы вернуться к своим примерам, вы бы не добавили подсказки типа в любом случае. Как читатель, так и mypy могут сказать, что ваше поле _volume должно быть числом с плавающей точкой: это очевидно, так должно быть, поскольку параметр является числом с плавающей точкой, а умножение числа с плавающей точкой на целое всегда будет вызывать другое значение с плавающей точкой.

Аналогично, вы бы не добавили аннотацию к вашей переменной my_volume. Так как return_volume() имеет подсказки типов, легко увидеть, какой тип он возвращает, и понять, что my_volume имеет тип float. (И если вы допустили ошибку и случайно подумали, что это нечто иное, чем поплавок, mypy поймет это за вас.)

0 голосов
/ 06 июля 2018

Для себя он начал писать подсказки типа везде, где это возможно. Это совсем не медленнее, и это облегчает, если вы вернетесь к своему старому коду в функции. Так что теперь использование их как можно более негативно, за исключением размера вашего файла python.

...