Jam*_*rts 5 python typing enumerate mypy
下面的代码:
from typing import Union
def process(actions: Union[list[str], list[int]]) -> None:
for pos, action in enumerate(actions):
act(action)
def act(action: Union[str, int]) -> None:
print(action)
Run Code Online (Sandbox Code Playgroud)
生成 mypy 错误: Argument 1 to "act" has incompatible type "object"; expected "Union[str, int]"
但是,当删除枚举函数时,输入就可以了:
from typing import Union
def process(actions: Union[list[str], list[int]]) -> None:
for action in actions:
act(action)
def act(action: Union[str, int]) -> None:
print(action)
Run Code Online (Sandbox Code Playgroud)
有谁知道枚举函数正在做什么来影响类型?这是 python 3.9 和 mypy 0.921
enumerate.__next__需要比可用的上下文更多的上下文才能获得比 更具体的返回类型Tuple[int, Any],因此我认为mypy需要对其本身进行修改才能进行enumerate(actions)产生Tuple[int,Union[str,int]]值的推理。
在此之前,您可以在将 的值传递action给 之前显式转换它的值act。
from typing import Union, cast
StrOrInt = Union[str, int]
def process(actions: Union[list[str], list[int]]) -> None:
for pos, action in enumerate(actions):
act(cast(StrOrInt, action))
def act(action: Union[str, int]) -> None:
print(action)
Run Code Online (Sandbox Code Playgroud)
您还可以制作process通用的(现在我已经想到了,这可能是一个更好的主意,因为它避免了cast运行时调用的开销)。
from typing import Union, cast, Iterable, TypeVar
T = TypeVar("T", str, int)
def process(actions: Iterable[T]) -> None:
for pos, action in enumerate(actions):
act(action)
def act(action: T) -> None:
print(action)
Run Code Online (Sandbox Code Playgroud)
这里,T不是类型的联合,而是单个具体类型,其标识通过调用来固定process。Iterable[T]是 或Iterable[str],Iterable[int]具体取决于您传递给的类型process。这修复了T对 的其余调用process,每次调用都act必须采用相同类型的参数。
AnIterable[str]或 anIterable[int]是有效的参数,绑定T到进程int或str在进程中。现在enumerate.__next__显然可以有一个特定的返回类型Tuple[int, T]。
| 归档时间: |
|
| 查看次数: |
2072 次 |
| 最近记录: |