实现异步迭代器 [英] Implementing an asynchronous iterator
问题描述
每个 PEP-492 我正在尝试实现一个异步迭代器,这样我就可以做到
Per PEP-492 I am trying to implement an asynchronous iterator, such that I can do e.g.
async for foo in bar:
...
这是一个简单的示例,类似于文档中的示例,它对实例化和异步迭代进行了非常基本的测试:
Here is a trivial example, similar to the one in the docs, with a very basic test of instantiation and async iteration:
import pytest
class TestImplementation:
def __aiter__(self):
return self
async def __anext__(self):
raise StopAsyncIteration
@pytest.mark.asyncio # note use of pytest-asyncio marker
async def test_async_for():
async for _ in TestImplementation():
pass
但是,当我执行测试套件时,我看到:
However, when I execute my test suite, I see:
=================================== FAILURES ===================================
________________________________ test_async_for ________________________________
@pytest.mark.asyncio
async def test_async_for():
> async for _ in TestImplementation():
E TypeError: 'async for' received an invalid object from __aiter__: TestImplementation
...: TypeError
===================== 1 failed, ... passed in 2.89 seconds ======================
为什么我的 TestImplementation
无效?据我所知,它符合协议:
Why does my TestImplementation
appear to be invalid? As far as I can tell it meets the protocol:
- 对象必须实现
__ aiter __
方法...返回异步迭代器对象. - 一个异步迭代器对象必须实现一个
__ anext __
方法...返回一个等待的对象. - 要停止迭代,
__ anext __
必须引发StopAsyncIteration
异常.
- An object must implement an
__aiter__
method ... returning an asynchronous iterator object. - An asynchronous iterator object must implement an
__anext__
method ... returning an awaitable. - To stop iteration
__anext__
must raise aStopAsyncIteration
exception.
使用最新版本的Python(3.5.1), py.test
(2.9.2)和 pytest-asyncio
(0.4.1)失败
This is failing with the latest released versions of Python (3.5.1), py.test
(2.9.2) and pytest-asyncio
(0.4.1).
推荐答案
如果您阅读 PEP 492在CPython 3.5.0中被接受,其中 PEP 492 was accepted in CPython 3.5.0 with 在3.5.2中(由于PEP 492被临时接受) In 3.5.2 (as PEP 492 was accepted on a provisional basis) the
因此,对于3.5.2之前的版本(2016年6月27日发行),该文档与如何编写有效的异步迭代器有些矛盾.3.5.0和3.5.1的固定版本如下: Therefore for versions prior to 3.5.2 (released 2016/6/27) the documentation is slightly out of step with how to write a working asynchronous iterator. The fixed version for 3.5.0 and 3.5.1 looks like: 这是在关闭 bug#27243 时引入的,在 This was introduced on closing bug #27243 and is a little clearer in the data model documentation, which also suggests a way of writing backwards compatible code. 这篇关于实现异步迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! __ aiter __
定义为方法,该方法应将可以解决的问题返回给异步迭代器.
__aiter__
defined as a
method, that was expected to return an awaitable resolving to an
asynchronous iterator. __ aiter __
协议已更新,可以直接返回异步迭代器.__aiter__
protocol was updated to return asynchronous iterators directly.class TestImplementation:
async def __aiter__(self):
# ^ note
return self
async def __anext__(self):
raise StopAsyncIteration