【发布时间】:2016-03-24 04:23:30
【问题描述】:
这是一个使用 asyncio 和 aiohttp 从多个网站下载主页的玩具示例:
import asyncio
import aiohttp
sites = [
"http://google.com",
"http://reddit.com",
"http://wikipedia.com",
"http://afpy.org",
"http://httpbin.org",
"http://stackoverflow.com",
"http://reddit.com"
]
async def main(sites):
for site in sites:
download(site)
async def download(site):
response = await client.get(site)
content = await response.read()
print(site, len(content))
loop = asyncio.get_event_loop()
client = aiohttp.ClientSession(loop=loop)
content = loop.run_until_complete(main(sites))
client.close()
如果我运行它,我会得到:
RuntimeWarning: coroutine 'download' was never awaited
但我不想等待。
在扭曲中我可以做到:
for site in sites:
download(site)
如果我没有明确地“屈服”或向返回的 Deferred 添加回调,它只会运行而不会阻塞或抱怨。我无法访问结果,但在这种情况下我不需要它。
在 JS 中我可以做到:
site.forEarch(site){
donwload(site)
}
再说一次,它不会阻塞,也不需要我做任何事情。
我找到了办法:
async def main(sites):
await asyncio.wait([download(site) for site in sites])
但是:
- 这真的不是很明显要找出来。我很难记住。
- 很难理解它的作用。 “waits”似乎是“i block”,但并没有清楚地传达它阻塞整个协程列表完成。
- 你不能传入一个生成器,它必须是一个真实的列表,我觉得这在 Python 中真的很不自然。
- 如果我只有一个 awaitable 怎么办?
- 如果我根本不想等待我的任务,而只是安排它们执行然后继续我的其余代码怎么办?
- 它比twisted 和JS 解决方案更冗长。
还有更好的方法吗?
【问题讨论】:
标签: python python-3.x async-await python-asyncio