lem*_*sss 12 python typing type-hinting python-3.x
什么是正确的类型提示x = []?
我的 PyCharm 编辑器中的类型检查器将此标记为错误:
labelframes: List[ttk.LabelFrame] = []
Run Code Online (Sandbox Code Playgroud)
'Optional' 不是一个选项,如:
labelframes: List[Optional[ttk.LabelFrame]] = []
Run Code Online (Sandbox Code Playgroud)
因为文档typing.Optional说明这相当于:
labelframes: List[Union[ttk.LabelFrame, None]] = []
Run Code Online (Sandbox Code Playgroud)
并且[None]不是[]。
我应该提到 PyCharm 也不喜欢这样:
labelframes: List[Union[ttk.LabelFrame, None]] = [None]
Run Code Online (Sandbox Code Playgroud)
无论我尝试什么类型的提示。PyCharm 将其标记为错误,“预期在此处返回我的类型提示,但没有返回”,因此我尝试了:
labelframes: Optional[List[ttk.LabelFrame, None]] = []
Run Code Online (Sandbox Code Playgroud)
那没有用。
我知道 PEP 526 有许多遵循以下模式的示例:
x: List[str] = []
Run Code Online (Sandbox Code Playgroud)
看看 PEP 484,特别是关于类型注释(变量注释的前身)的部分,这确实看起来像是 PyCharm 的检查器的一个错误。
引自 PEP:
在非存根代码中,有一个类似的特例:
Run Code Online (Sandbox Code Playgroud)from typing import IO stream = None # type: IO[str]类型检查器不应对此抱怨(尽管值
None与给定类型不匹配),也不应将推断类型更改为Optional[...](尽管规则对默认值为 None 的带注释的参数执行此操作)。这里的假设是其他代码将确保变量被赋予正确类型的值,并且所有使用都可以假设变量具有给定类型。
因此,以类似的方式,类型检查器(就像mypy当前所做的那样)不应该抱怨您提供的初始化值与注释不严格匹配的事实。
首先,我们为一个空列表编写示例代码,并使用 mypy.txt 进行检查。
from typing_extensions import reveal_type
l = []
reveal_type(l)
Run Code Online (Sandbox Code Playgroud)
现在让我们在 shell 中运行它,如下所示。
$ mypy test.py
test.py:4: error: Need type annotation for "l" (hint: "l: List[<type>] = ...")
test.py:6: note: Revealed type is "builtins.list[Any]"
Found 1 error in 1 file (checked 1 source file)
Run Code Online (Sandbox Code Playgroud)
现在请注意第二行,因为它表示类型是List[Any]。
让我们进行更改并重新运行
from typing import Any, List
from typing_extensions import reveal_type
l : List[Any] = []
reveal_type(l)
Run Code Online (Sandbox Code Playgroud)
现在运行 mypy。
$ mypy test.py
test.py:6: note: Revealed type is "builtins.list[Any]"
Success: no issues found in 1 source file
Run Code Online (Sandbox Code Playgroud)