Ошибка типа из Python 3 для асинхронного цикла

Я изучаю относительно новые асинхронные функции Python. Я нашел это в PEP 492:

Ниже приведен служебный класс, который преобразует обычный итератор в асинхронный. Хотя это не очень полезно, код иллюстрирует взаимосвязь между обычными и асинхронными итераторами.

class AsyncIteratorWrapper:
    def __init__(self, obj):
        self._it = iter(obj)

    def __aiter__(self):
        return self

    async def __anext__(self):
        try:
            value = next(self._it)
        except StopIteration:
            raise StopAsyncIteration
        return value

async for letter in AsyncIteratorWrapper("abc"):
    print(letter)

Я попытался запустить этот код, добавив async for Цикл для функции, а затем вызывая это с помощью цикла событий.

Полный пример кода (запустить в интерпретаторе):

class AsyncIteratorWrapper:
    def __init__(self, obj):
        self._it = iter(obj)
    def __aiter__(self):
        return self
    async def __anext__(self):
        try:
            value = next(self._it)
        except StopIteration:
            raise StopAsyncIteration
        return value

async def aprint(str):
  async for letter in AsyncIteratorWrapper(str):
    print(letter)

import asyncio
loop = asyncio.get_event_loop()
co = aprint("abcde")
loop.run_until_complete(co)

Тем не менее, я получаю сообщение об ошибке:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/rh/rh-python35/root/usr/lib64/python3.5/asyncio/base_events.py", line 337, in run_until_complete
    return future.result()
  File "/opt/rh/rh-python35/root/usr/lib64/python3.5/asyncio/futures.py", line 274, in result
    raise self._exception
  File "/opt/rh/rh-python35/root/usr/lib64/python3.5/asyncio/tasks.py", line 239, in _step
    result = coro.send(None)
  File "<stdin>", line 2, in aprint
TypeError: 'async for' received an invalid object from __aiter__: AsyncIteratorWrapper

Что я делаю неправильно? Как можно исправить этот пример? Я немного удивлен, что код прямо из PEP не работает.

Я использую Python версии 3.5.1.

1 ответ

Решение

Код, который вы используете, работает с python 3.5.2+.

Из Python 3.5.2 __aiter__ может напрямую возвращать асинхронные итераторы. Больше здесь

Ошибка, которую вы получили, произошла из-за более старого Python(3.5.1), и поэтому он возвращал неправильный тип.

Другие вопросы по тегам