为什么 mypy 在无法注释时抱怨列表理解?

c z*_*c z 4 python mypy python-typing

当不可能使用 MyPy 注释这样的变量时,为什么 Mypy 抱怨它需要对列表理解变量进行类型注释?

具体来说,我该如何解决以下错误:

from enum import EnumMeta

def spam( y: EnumMeta ):
    return [[x.value] for x in y]  Mypy: Need type annotation for 'x' 
Run Code Online (Sandbox Code Playgroud)

cast不起作用

return [[cast(Enum, x).value] for x in y]  Mypy: Need type annotation for 'x'  
Run Code Online (Sandbox Code Playgroud)

即使Mypy不支持注释(x:Enum)在这种情况下,我看到了使用的变量可以使用注释的cast看到这个帖子)。但是,这cast(Enum, x) 并不能阻止 Mypy 抱怨变量没有首先被注释。

#type:不起作用

return [[x.value] for x in y] # type: Enum  Mypy: Misplaced type annotation
Run Code Online (Sandbox Code Playgroud)

我还看到for可以使用注释对循环变量进行注释,# type:参见这篇文章)。但是,# type: Enum不适用于列表理解的for.

Mis*_*agi 5

在列表理解中,迭代器必须被强制转换而不是元素。

from typing import Iterable, cast
from enum import EnumMeta, Enum

def spam(y: EnumMeta):
    return [[x.value] for x in cast(Iterable[Enum], y)]
Run Code Online (Sandbox Code Playgroud)

这也允许mypy推断类型x。此外,在运行时它只执行 1 次强制转换而不是 n 次强制转换。

如果spam可以消化任何产生枚举的可迭代对象,则直接输入提示更容易。

from typing import Iterable
from enum import Enum

def spam(y: Iterable[Enum]):
    return [[x.value] for x in y]
Run Code Online (Sandbox Code Playgroud)


Ale*_*ood 5

MisterMyagi 的答案是针对这种具体情况的最佳解决方案。然而,值得注意的是,也可以在定义变量之前声明该变量的类型。以下内容也通过 MyPy

from enum import Enum

def spam(y: type[Enum]):
    x: Enum
    return [[x.value] for x in y]
Run Code Online (Sandbox Code Playgroud)