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

问题描述 投票:0回答: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 认为这是一个错误:

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

python python-3.x pycharm python-typing
3个回答
156
投票

您需要导入

typing
模块。根据文档:

生成器函数的返回类型可以用泛型注释 类型

Generator[yield_type, send_type, return_type]
提供者
typing.py
模块

试试这个方法:

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 月提交的。他们可能修复了它并将修改推送到同一版本中。


113
投票

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

我正在使用下面的类型规范,使用

Iterator[int]
而不是 Generator。验证没问题。我想这已经清楚多了。它更好地描述了代码意图,并且受到Python 文档的推荐。

from typing import Iterator

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

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

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

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

from collections.abc import Iterator

4
投票

Iterator
Generator
Iterable
在细节上略有不同,并且携带不同类型的信息,因此了解差异可能有助于为您的代码选择正确的:

  • Iterator
    只是一个实现迭代器协议的对象(包括
    __iter__()
    __next__()
    方法),

  • Generator
    更具体,因为它不仅表示该函数返回
    Iterator
    ,而且还表示它是使用生成器实现的(即使用
    yield
    表达式的函数)。生成器函数返回迭代器。

  • 最后是

    Iterable
    ,它比
    Iterator
    更通用,因为
    Iterable
    可以是任何可以迭代的对象,包括但不限于列表、元组和迭代器。可迭代对象必须具有返回迭代器的
    __iter__()
    方法,或具有从
    __getitem__()
    开始的顺序索引的
    0
    方法。

所以如何输入提示主要取决于你的代码真正在做什么:

  • 当函数需要接受任何可迭代对象而不考虑迭代器的确切类型时,请使用
    Iterable
  • 当函数预计专门用于迭代器对象时,请使用
    Iterator
    ,而不指定迭代器的确切子类型。
  • 使用
    Generator
    显式指示函数返回/接受生成器对象,并可选择指定可以发送到生成器或从生成器返回的值的类型。
© www.soinside.com 2019 - 2024. All rights reserved.