[英]enumerate causes incompatible type mypy error
以下代码:
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)
生成 mypy 错误: Argument 1 to "act" has incompatible type "object"; expected "Union[str, int]"
Argument 1 to "act" has incompatible type "object"; expected "Union[str, int]"
但是,当删除枚举 function 时,打字很好:
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)
有谁知道枚举 function 正在做什么来影响这些类型? 这是 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)
您还可以使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)
在这里, T
不是类型的联合,而是单个具体类型,其标识由对process
的调用确定。 Iterable[T]
是Iterable[str]
或Iterable[int]
,具体取决于您传递给process
的类型。 这修复了对process
的调用的 rest 的T
,每个对act
的调用都必须采用相同类型的参数。
Iterable[str]
或Iterable[int]
是一个有效参数,将T
绑定到进程中的int
或str
。 现在enumerate.__next__
显然可以有一个特定的返回类型Tuple[int, T]
。
我不知道它是如何影响类型的。 我知道使用 len() 可以以相同的方式工作。 它速度较慢,但如果它解决了问题,它可能是值得的。 抱歉,帮不上忙
似乎 mypy 无法推断类型并推广到 object。 可能值得在他们身边打开一个问题。 作为一种解决方法,您可以注释“操作”。 这将消除错误。 如果您从typing
中导入(旧版) List
,它会起作用吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.