如何使用async for循环迭代列表?

Max*_*ith 11 python iterator asynchronous python-3.x python-asyncio

所以我需要为列表中的所有项调用异步函数.这可以是一个URL列表和一个使用aiohttp的异步函数,它从每个URL获取响应.现在显然我不能做到以下几点:

['www.google.com','www.youtube.com','www.aol.com']中的url async:

我可以使用普通的for循环但是我的代码将同步操作,我失去了获得异步响应获取功能的好处和速度.

有什么方法可以转换列表,以便上述工作吗?我只需要将列表的iter()更改为aiter()方法吗?可以通过子类化列表来实现吗?也许将它封装在一个类中?

提前致谢!

(PS:我正在使用python 3.6)

Vin*_*ent 14

使用asyncio.as_completed:

for future in asyncio.as_completed(map(fetch, urls)):
    result = await future
Run Code Online (Sandbox Code Playgroud)

asyncio.gather:

results = await asyncio.gather(map(fetch, urls))
Run Code Online (Sandbox Code Playgroud)

编辑:如果你不介意有外部依赖,你可以使用aiostream.stream.map:

from aiostream import stream, pipe

async def fetch_many(urls):
    xs = stream.iterate(urls) | pipe.map(fetch, ordered=True, task_limit=10)
    async for result in xs:
        print(result)
Run Code Online (Sandbox Code Playgroud)

您可以fetch使用task_limit参数控制同时运行的协同程序的数量,并选择是按顺序获取结果还是尽快获得结果.

请参阅本演示文档中的更多示例.

  • 但是在这里,您使用的是map,它本质上就像是普通的for循环,将函数应用于列表中的每个元素。为什么这会更快?它又如何异步?映射还受提取功能可以接收的参数数量限制。我还计划通过aiohttp会话。 (2认同)
  • @MaxSmith请参阅我的编辑,以解决您的套接字问题。 (2认同)

qua*_*nom 7

请注意,Vincents 的回答有一个部分问题:
您必须在函数前面有一个splatter 运算符map,否则asyncio.gather会尝试使用整个列表。所以这样做:

results = await asyncio.gather(*map(fetch, url))
Run Code Online (Sandbox Code Playgroud)