Lau*_*che 7 python python-3.x mypy
此函数类型注释是否正确?
import subprocess
from os import PathLike
from typing import Union, Sequence, Any
def run(shell_command: Union[bytes, str, Sequence[Union[bytes, str, PathLike]]], **subprocess_run_kwargs: Any) -> int:
return subprocess.run(shell_command, check=True, shell=True, **subprocess_run_kwargs).returncode
Run Code Online (Sandbox Code Playgroud)
我猜不是,因为我得到:
he\other.py:6: error: Missing type parameters for generic type
要得到同样的错误,然后将上面的代码保存在 中other.py
,然后:
$ pip install mypy
$ mypy --strict other.py
Run Code Online (Sandbox Code Playgroud)
如 sanyash 的回答中所述,os.PathLike
被定义为泛型类型。您可以查看typeshed repo中的存根。但是,os.PathLike
仅在存根文件中是通用的,可导入的实现os
不是.
不指定类型 var 参数 ( path: PathLike
) 会导致 mypy 错误。指定类型 var 参数 ( path: PathLike[Any]
) 会导致 Python 解释器(运行时)错误。
这个确切的问题已在 mypy 存储库中作为#5667 提出。因此PR #5833扩展了 mypy 文档:
添加的部分指出了三种处理方法:
可以通过特殊from __future__ import annotations
导入禁用 Python 解释器(在运行时)对注释的解释,请参见此处。这计划成为 Python 3.10 中的默认设置,并解决一堆与注释相关的问题。
from __future__ import annotations
from os import PathLike
import subprocess
from typing import Any, Sequence, Union
def run(shell_command: Union[bytes, str, Sequence[Union[bytes, str, PathLike[Any]]]], **subprocess_run_kwargs: Any) -> int:
return subprocess.run(shell_command, check=True, shell=True, **subprocess_run_kwargs).returncode
Run Code Online (Sandbox Code Playgroud)
使用typing.TYPE_CHECKING
依赖于类型检查或Python解释(运行时)是否解释该文件以提供不同的注释。
from os import PathLike
import subprocess
from typing import Any, Sequence, TYPE_CHECKING, Union
if TYPE_CHECKING:
BasePathLike = PathLike[Any]
else:
BasePathLike = PathLike
def run(shell_command: Union[bytes, str, Sequence[Union[bytes, str, BasePathLike]]], **subprocess_run_kwargs: Any) -> int:
return subprocess.run(shell_command, check=True, shell=True, **subprocess_run_kwargs).returncode
Run Code Online (Sandbox Code Playgroud)
以字符串形式提供注释。Python 解释器(运行时)不会解释注释,但 mypy 会获取正确的含义。
import subprocess
from typing import Any, Sequence, Union
def run(shell_command: Union[bytes, str, Sequence[Union[bytes, str, 'PathLike[Any]']]], **subprocess_run_kwargs: Any) -> int:
return subprocess.run(shell_command, check=True, shell=True, **subprocess_run_kwargs).returncode
Run Code Online (Sandbox Code Playgroud)
PathLike
是泛型类型,因此您需要将其与类型参数一起使用(AnyStr
例如):
import subprocess
from os import PathLike
from typing import Union, Sequence, Any, AnyStr
def run(shell_command: Union[bytes, str, Sequence[Union[bytes, str, PathLike[AnyStr]]]], **subprocess_run_kwargs: Any) -> int:
return subprocess.run(shell_command, check=True, shell=True, **subprocess_run_kwargs).returncode
Run Code Online (Sandbox Code Playgroud)
相关问题:
更新
抱歉,我没有在运行时检查这段代码。通过一些技巧,可以编写一个解决方法:
import subprocess
from os import PathLike as BasePathLike
from typing import Union, Sequence, Any, AnyStr, TYPE_CHECKING
import abc
if TYPE_CHECKING:
PathLike = BasePathLike
else:
class FakeGenericMeta(abc.ABCMeta):
def __getitem__(self, item):
return self
class PathLike(BasePathLike, metaclass=FakeGenericMeta):
pass
def run(shell_command: Union[bytes, str, Sequence[Union[bytes, str, PathLike[AnyStr]]]], **subprocess_run_kwargs: Any) -> int:
return subprocess.run(shell_command, check=True, shell=True, **subprocess_run_kwargs).returncode
Run Code Online (Sandbox Code Playgroud)
与此解决方法相关的问题:
归档时间: |
|
查看次数: |
4395 次 |
最近记录: |