ChatGPT解决这个技术问题 Extra ChatGPT

如何在 Python 3 中键入提示生成器?

根据 PEP-484,我们应该能够键入提示生成器函数,如下所示:

from typing import Generator

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

for i in generate():
    print(i)

但是,列表推导在 PyCharm 中给出了以下错误。

预期的 'collections.Iterable',得到了 'Generator[int, None, None]' 而不是 ... (⌘F1)

知道为什么 PyCharm 将其视为错误吗?

阅读一些答案后进行一些澄清。我正在使用 PyCharm Community Edition 2016.3.2(最新版本)并已导入 typing.Generator(已在代码中更新)。上面的代码运行得很好,但是 PyCharm 认为这是一个错误:

https://i.stack.imgur.com/PGSwC.png

所以,我想知道这实际上是一个错误还是 PyCharm 中不受支持的功能。

当您将代码更改为 ideone.com/IwHbT0 时会发生什么?
我使用 Pycharm 2017.1 EAP,它似乎已修复。
EAP 确实解决了这个问题。非常感谢您。
@MikeWilliamson 是的,这是一个编辑:stackoverflow.com/revisions/42531143/2。看起来真正的问题是 PyCharm,而不是 Python。最重要的答案也已更新以提及这一点。我不知道按照 SO 标准应该如何处理这个令人困惑的 Q/A。

佚名

您需要导入 typing 模块。根据文档:

生成器函数的返回类型可以通过typing.py模块提供的泛型Generator[yield_type, send_type, return_type]注解

试试这种方式:

from typing import Generator


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

以上将有预期的结果:

l = [i for i in generate()]

输出:

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

正如评论中所指出的,您可能不会使用最新版本的 PyCharm。尝试切换到 2016.3.2 版本,您可能会没事。不幸的是,根据@AshwiniChaudhary 的评论,这是一个众所周知的错误。

此外,报告的问题(针对 PyCharm 的最后一个版本)是在去年 12 月提交的。他们可能修复了它并将修改推送到相同的版本。


对于 OP,这不应该导致 Generator NameError 吗?
@AshwiniChaudhary 为什么会这样?我刚刚对其进行了测试,它的工作原理完全一样。
问题不在于输出,问题在于 PyCharm 抱怨返回类型。你在 PyCharm 中测试过吗?
@AshwiniChaudhary 是正确的,OP 已经进行了导入(即使它没有显示在他们的代码片段中),否则他们会得到一个 NameError
send_type 是什么?
n
neves

这不是问题的直接答案,但我认为这是一个更好的解决方案。

我正在使用下面的打字规范,使用 Iterator[int] 而不是生成器。验证正常。我认为它更清晰。它更好地描述了代码意图,并被 Python docs 推荐。

from typing import Iterator

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

如果您将生成器更改为列表或其他可迭代对象,它也将允许将来进行重构。

我正在使用带有 PyLance 的 Visual Studio Code 进行输入验证。 PyCharm mypy 应该具有相同的行为。


我不确定为什么这被否决了。 python 文档本身指出,可以将 Iterator[YieldType]Iterable[YieldType] 用于生成器,它们只产生。请参阅docs.python.org/3.6/library/typing.html#typing.Generator
from collections.abc import Iterator 是新的优选方式。请参阅docs.python.org/3.10/library/typing.html#typing.Iterable