путаница аннотирующей функции генератора в качестве итератора - PullRequest
0 голосов
/ 03 мая 2018

В питоне набрав документации написано:

В качестве альтернативы, аннотируйте ваш генератор как имеющий тип возвращаемого значения 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] не вызывается

  • ошибка: аргумент 1 для "print_infinite_stream" имеет несовместимый тип "Callable [[int], Iterator [int]]"; ожидаемый "Iterator [int]"

Я смущен, почему я получаю эти ошибки, поскольку я работал в соответствии с документацией и установил последние версии python (3.6.5) и mypy (0.590). Что здесь не так?

1 Ответ

0 голосов
/ 04 мая 2018

комментирует ваш генератор как возвращаемый тип 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], и это именно то, что вы хотите.

...