【问题标题】:TypeError from Python 3 async for loop来自 Python 3 异步 for 循环的 TypeError
【发布时间】:2017-07-26 22:08:57
【问题描述】:

我正在学习 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 版。

【问题讨论】:

  • 它正在处理python3.6
  • Working on 3.5 too - 查看我发现的更改日志“3.5.2 版更改:从 CPython 3.5.2 开始,aiter 可以直接返回异步迭代器. "
  • 对于 3.5 中的几个版本 __aiter__ 被认为是异步的,但随后语义更改为直接返回异步迭代,所以只需更新到更新版本的 python 就可以了。
  • @Orange 你介意链接到那个,这样我就不用费力找到它了吗?

标签: python asynchronous python-3.5


【解决方案1】:

您使用的代码适用于 python 3.5.2+。

从 Python 3.5.2 __aiter__ 可以直接返回异步迭代器。 More here

您收到的错误是因为较旧的 python(3.5.1),因此它返回了错误的类型。

【讨论】:

    猜你喜欢
    • 2017-05-19
    • 1970-01-01
    • 2010-10-01
    • 2017-07-29
    • 2015-04-11
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 2018-09-24
    相关资源
    最近更新 更多