Я недавно начал использовать подсказки типа в своем коде и до сих пор нашел, что они (в основном) очень полезны.
Однако, одна вещь, которая мне действительно не нравится, этосинтаксис, заставляющий средство проверки типов предполагать, что переменная имеет определенный тип.Учитывая этот пример:
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))