在Python中进行类型提示时,我有两个选项可将表达式标记为特定类型:
from typing import cast
foo = cast(str, expression)
bar = expression # type: str
两者之间有什么区别?
给我的印象是,有时使用cast
可行,而有时我必须使用注释。但是我还没有找到一种模式。不幸的是,我目前手头没有一个代码示例,而另一个却不能。
答案 0 :(得分:1)
# type: ignore
的意思是“请使该行中出现的与类型相关的错误保持沉默”。
cast(TYPE, EXPR)
的意思是“我知道您认为X的EXPR类型,但我希望您假设该类型实际上是TYPE,好吗?”
当遇到无法解决的类型检查器的某些限制时,通常使用# type: ignore
。例如,假设您尝试导入一些没有存根或类型定义的第三方库。在这种情况下,请执行以下操作:
# Results in errors like"
# error: No library stub file for module 'library_with_no_hints'
import library_with_no_hints
...通常会导致错误。但是您可以使用# type: ignore
来消除该错误:
import library_with_no_hints # type: ignore
通常,当您有其他带外信息时,cast
会使类型检查器不知道某些类型X实际上仅是Y。例如:
def parse_config(assume_normalized: bool, thing: List[Union[int, str]]) -> List[int]:
if assume_normalized:
# The type-checker thinks that 'thing' is a List[Union[int, str]];
# we now force it to assume it's really a List[int] instead.
return cast(List[int], thing)
else:
output = []
for item in thing:
if isinstance(item, int):
output.append(item)
else:
output.append(parse(item))
return output
您通常会在以下情况下看到强制转换:a)您正在使用大量反序列化/序列化样式代码,并且需要将泛型类型转换为更具体的类型,b)您正在做具有多个继承的奇怪操作,或c)您的代码设计不当,并且已经陷入困境。
我个人几乎从不使用强制转换-如果可以的话,我会尽量避免使用强制转换,否则将至少使用isinstance check之类的方法,因此如果我的假设最终是错误的话,我的代码将在运行时崩溃。 >
(我也尝试忽略# type: ignore
,但有时它们最终会成为一种必不可少的弊端,可以帮助您解决类型检查器中的限制。)
如果您打算在代码库中使用类型忽略或强制类型转换,还应该考虑配置类型检查器,以便在不必要的地方使用它们时向您发出警告。
例如,对于mypy,您可以传递--warn-unused-ignores
和--warn-unused-casts
标志。