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

时间:2018-05-03 12:08:51

标签: python type-hinting mypy

在python typing文档中写道:

  

或者,将您的生成器注释为具有Iterable [YieldType]或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我会遇到两个错误:

  • 错误:Iterator [int]无法调用

  • 错误:“print_infinite_stream”的参数1具有不兼容的类型“Callable [[int],Iterator [int]]”;预期“Iterator [int]”

我很困惑为什么我得到这些错误,因为我根据文档工作并安装了最新的python(3.6.5)和mypy(0.590)。这有什么不对?

1 个答案:

答案 0 :(得分:2)

  

将您的生成器注释为具有Iterable [YieldType]或Iterator [YieldType]的返回类型

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

reveal_type(infinite_stream),您将获得类似Callable[[int], Iterator[int]]的内容。

你想要的是函数的返回值,即实际的迭代器。

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]这样的东西,这正是你想要的。