Подсказки типа Python - лучший синтаксис для cast ()? - PullRequest
4 голосов
/ 01 апреля 2019

Я недавно начал использовать подсказки типа в своем коде и до сих пор нашел, что они (в основном) очень полезны.

Однако, одна вещь, которая мне действительно не нравится, этосинтаксис, заставляющий средство проверки типов предполагать, что переменная имеет определенный тип.Учитывая этот пример:

import itertools
from typing import Iterable, Tuple
x: Iterable[Tuple[str, str]] = itertools.combinations('abc', 2)
# error: Incompatible types in assignment (expression has type "Iterable[Tuple[str, ...]]", variable has type "List[Tuple[str, str]]")

Насколько я могу сказать, рекомендуемый способ обойти это - явно cast объект, чтобы заставить средство проверки типов использовать указанныйтипа, например:

import itertools
from typing import Iterable, Tuple, cast
x = cast(Iterable[Tuple[str, str]], itertools.combinations('abc', 2))

Лично я нахожу это решение немного грубым.Моя главная проблема заключается в том, что неопытному читателю не ясно, что cast предназначен исключительно для того, чтобы помочь статическому анализатору.(Если бы я еще не знал, я бы предположил, исходя из имени и контекста, что он преобразует и делает копию в объект указанного типа, когда действительно нет времени выполнения.)

cast выглядит как любой старый вызов функции.Когда я вижу, что функция вызывается для значения, я ожидаю, что значение будет видоизменено и / или возникнут некоторые другие побочные эффекты, но в этом случае единственным побочным эффектом является то, что mypy перестает жаловаться.Сами подсказки типа имеют особый синтаксис, но я чувствую, что это стирает строки со смесью нового синтаксиса ввода и традиционного синтаксиса Python.(Это уже немного размыто, поскольку вы должны import типы и можете их составлять, но это другое обсуждение.)

Существует ли альтернативный синтаксис для cast -подобного поведения?Я ничего не нашел, но я надеялся на что-то вроде:

x1 = itertools.combinations('abc', 2)) # cast: Iterable[Tuple[str, str]] 

x2: Iterable[Tuple[str, str]] = itertools.combinations('abc', 2)) # type: cast

x3: Cast[Iterable[Tuple[str, str]]] = itertools.combinations('abc', 2))
...