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

问题描述 投票:0回答:1

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 我遇到两个错误:

  • 错误:迭代器[int]不可调用

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

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

python mypy type-hinting python-typing
1个回答
15
投票

将生成器注释为具有 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
可以处理 any 迭代器,而不仅仅是生成器函数。如果您
reveal_type(infinite_stream(5))
您应该得到类似
Iterator[int]
的东西,这正是您想要的。

© www.soinside.com 2019 - 2024. All rights reserved.