如何在Python 3.6中使用异步生成器?

13

我需要处理来自服务器的多个页面数据。我想做一个生成器,就像这样。不幸的是,我收到了TypeError: 'async_generator' object is not iterable

async def get_data():
    i = 0
    while i < 3:
        i += 1
        data = await http_call()  # call to http-server here
        yield data

data = [i for i in get_data()]  # inside a loop

下一个变量会产生TypeError: object async_generator无法在'await'表达式中使用

data = [i for i in await get_data()]  # inside a loop
1个回答

25

在您的推导式中使用async for。请参阅PEP 530 -- 异步推导式

data = [i async for i in get_data()]

根据您使用的Python版本,这可能仅在async def函数中可用。


请注意,这不会对所有页面进行异步调用。 - Aaron_ab
@Aaron_ab 你是什么意思? - Patrick Haugh
如果我们记录每次访问 get_data 的开始和结束,我们会发现 get_data1 开始和结束,然后是 get_data2 等等...没有并发。 - Aaron_ab
“async”并不像抢占式多线程那样意味着“并发”。由于GIL的存在,纯Python级别上不存在抢占式多线程。 “async”意味着合作式多任务处理,这意味着开发人员在每个“await”表达式处明确放弃对其他当前暂停的协程和异步生成器的控制权。在没有显式的多线程或多进程的情况下,异步生成器仍然按顺序产生它们的结果(即非并发)。 - Cecil Curry
如果您想在异步编程范式下实现真正的并发,请考虑使用asyncio.Queue类和asyncio.as_completed()函数来处理I/O绑定操作,或者使用async.run_in_executor()函数来处理CPU绑定操作。 - Cecil Curry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接