我最近开始在代码中使用type hints,到目前为止,发现它们(主要)非常有帮助。
但是,我真正不喜欢的一件事是强制类型检查器假定变量属于某种类型的语法。给出以下示例:
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))
答案 0 :(得分:1)
实际上,最新版本的Mypy确实返回了正确的类型Iterator[Tuple[str, str]]
。
此更改是在PR https://github.com/python/typeshed/pull/4309中的Typeshed中引入的。
如果无法将mypy更新为最新版本,则可以从typeshed
检出最新版本,并使用配置选项custom_typeshed_dir
。
有关更多详细信息,请参见https://mypy.readthedocs.io/en/stable/config_file.html#confval-custom_typeshed_dir。