将生成器函数注释为迭代器的混淆

confusion of annotating generator function as iterator

在 python typing 文档中写道:

Alternatively, annotate your generator as having a return type of either Iterable[YieldType] or Iterator[YieldType]:

def infinite_stream(start: int) -> Iterator[int]:
    while True:
        yield start
        start += 1

我写了一个打印无限流的非常简单的例子。我有一个生成器函数,它被传递给另一个函数然后被调用。

from typing import Iterator


def infinite_stream(start: int) -> Iterator[int]:
    while True:
        yield start
        start += 1


def print_infinite_stream(inf_iterator: Iterator[int]):
    for x in inf_iterator(5):
        print(x)


print_infinite_stream(infinite_stream)

使用 mypy 我得到两个错误:

我很困惑为什么我在根据文档工作并安装了最新的 python (3.6.5) 和 mypy (0.590) 时收到这些错误。这里有什么问题?

annotate your generator as having a return type of either Iterable[YieldType] or Iterator[YieldType]

生成器函数 return 生成器,它们本身不是生成器。如果你这样做:

reveal_type(infinite_stream),你会得到类似 Callable[[int], Iterator[int]].

的东西

你要的是函数的return值,实际的迭代器。

from typing import Iterator


def infinite_stream(start: int) -> Iterator[int]:
    while True:
        yield start
        start += 1


def print_infinite_stream(inf_iterator: Iterator[int]):
    for x in inf_iterator:
        print(x)


print_infinite_stream(infinite_stream(5))

这更有意义,因为现在 print_infinite_stream 处理 任何 迭代器,而不仅仅是您的生成器函数。如果你 reveal_type(infinite_stream(5)) 你应该得到类似 Iterator[int] 的东西,这正是你想要的。