繁体   English   中英

enumerate 导致不兼容的类型 mypy 错误

[英]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绑定到进程中的intstr 现在enumerate.__next__显然可以有一个特定的返回类型Tuple[int, T]

我不知道它是如何影响类型的。 我知道使用 len() 可以以相同的方式工作。 它速度较慢,但如果它解决了问题,它可能是值得的。 抱歉,帮不上忙

似乎 mypy 无法推断类型并推广到 object。 可能值得在他们身边打开一个问题。 作为一种解决方法,您可以注释“操作”。 这将消除错误。 如果您从typing中导入(旧版) List ,它会起作用吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM