How to type hint a generator in Python 3?

According to PEP-484, we should be able to type hinting a generator function as follows:

from typing import Generator


def generate() -> Generator[int, None, None]:
for i in range(10):
yield i


for i in generate():
print(i)

However, the list comprehension gives the following error in PyCharm.

Expected 'collections.Iterable', got 'Generator[int, None, None]' instead less... (⌘F1)

Any idea why PyCharm is considering this as error?


A few clarification after reading some answers. I am using PyCharm Community Edition 2016.3.2 (the latest version) and have imported the typing.Generator (updated in the code). The above code runs just fine, but PyCharm considers this an error:

enter image description here

So, I'm wondering if this is actually an error or an unsupported feature in PyCharm.

58170 次浏览

您需要导入 typing模块:

泛型可以对生成器函数的返回类型进行注释 type Generator[yield_type, send_type, return_type] provided by typing.py模块

Try this way instead:

from typing import Generator




def generate() -> Generator[int, None, None]:
for i in range(10):
yield i

The above will have the desired result:

l = [i for i in generate()]

Output:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


正如在评论中指出的,您可能不会使用 PyCharm 的最后一个版本。尝试切换到版本 2016.3.2和你的 也许吧是好的。不幸的是,根据@AshwiniChaudhary 的评论,这是一个众所周知的错误。

此外,报道的问题(针对 PyCharm 的最新版本)于去年12月提交。他们可能修复了它,并将修改推入了相同的版本。

This isn't a direct answer to the question, but I think it is a better solution.

我使用的是下面的类型规范,使用的是 Iterator[int]而不是 Generator。验证没问题。我觉得现在清楚多了。它更好地描述了代码的意图,是由 Python docs推荐的。

from typing import Iterator


def generate() -> Iterator[int]:
for i in range(10):
yield i

如果您更改了列表或其他可迭代文件的 Generator,它还将允许未来的重构。

我使用 VisualStudio 代码和 PyLance 进行类型验证。

如果使用 Python 3.10或更高版本,请将上面的 import 命令更改为:

from collections.abc import Iterator