Python 3.x 如何获取异步协同程序python的返回值

Python 3.x 如何获取异步协同程序python的返回值,python-3.x,python-asyncio,Python 3.x,Python Asyncio,我是python新手,正在尝试学习asyncio模块。我对从异步任务中获取返回值感到沮丧。有一篇文章讨论了这个主题,但它不能告诉哪个任务返回哪个值(假设某个网页的响应比另一个更快)。 下面的代码试图同时获取三个web页面,而不是逐个获取 import asyncio import aiohttp async def fetch(url): async with aiohttp.ClientSession() as session:

我是python新手,正在尝试学习asyncio模块。我对从异步任务中获取返回值感到沮丧。有一篇文章讨论了这个主题,但它不能告诉哪个任务返回哪个值(假设某个网页的响应比另一个更快)。
下面的代码试图同时获取三个web页面,而不是逐个获取

    import asyncio
    import aiohttp

    async def fetch(url):
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as resp:
                assert resp.status == 200
                return await resp.text()

    def compile_all(urls):
        tasks = []
        for url in urls:
            tasks.append(asyncio.ensure_future(fetch(url)))
        return tasks

    urls = ['https://python.org', 'https://google.com', 'https://amazon.com']
    tasks = compile_all(urls)
    loop = asyncio.get_event_loop()
    a, b, c = loop.run_until_complete(asyncio.gather(*tasks))
    loop.close()

    print(a)
    print(b)
    print(c)
首先,尽管它确实打印了一些html文档,但还是遇到了Runtimeerror:事件循环已关闭

第二个问题是:这真的能保证a、b、c按照url[0]、url[1]、url[2]网页的顺序与url列表相对应吗?(我假设异步任务执行不能保证这一点)

第三,还有其他更好的方法吗?在这种情况下,我应该使用队列吗?如果是,如何进行


任何帮助都将不胜感激。

结果的顺序将与URL的顺序相对应。请查看以下文档:

如果成功完成所有等待项,则结果为 返回值的聚合列表。结果值的顺序 对应于aws中可等待项的顺序


要在任务完成时处理任务,可以使用。这有关于如何使用它的更多信息。

使用
wait
将暂停函数的执行,直到它返回某个内容,但不会阻止其他
异步
函数运行。如果您是python新手,我不建议您使用
asyncio
进行多处理,因为它非常复杂,最适合经验丰富的人使用。此外,您的问题问得很奇怪。你所说的“Python网页”是什么意思?必须使用asyncio,这是工作所要求的,这也是我需要学习它的原因。。我已经修改了我的问题表达,很抱歉。我理解。但是你说的“Python网页”是什么意思?我无法重现你观察到的
运行时错误。是的,结果将与URL的顺序相对应,不管它们的完成顺序如何。谢谢你的回答。这确认了gather()仅在所有任务完成后返回结果列表。。。但是,使用asyncio同时获取网页(或执行I/O任务)与我的意图背道而驰。我使用asyncio的目的是避免被任何响应速度慢的网站阻止。最后,这就像是一个接一个地把它们取出来。。。。还有其他更好的方法吗?@Spark您可以在aiohttp客户端会话中设置一个中断缓慢的网站。谢谢。设置超时意味着我必须放弃那些缓慢的网站,即使它们可能只是偶尔缓慢。我的想法是假设事件循环可以通过类似于先进先出缓冲区或队列的机制从首先完成的任务返回结果,因此多任务的异步执行实际上变成了管道吐出结果…@Spark这不一样。如果您要获取分别需要1、2和3秒的站点,则逐个获取它们将需要6秒。使用
gather()
获取它们只需3秒钟,因此显然更好。如果您想对前一秒做出反应,可以使用
asyncio.as\u completed
@user4815162342。非常感谢,虽然它返回了生成器,但它看起来与我使用asyncio的意图完全一样。我得到了三个html文档,google率先发布(正如预期的那样)…关于运行时错误,我有时无法复制它,但我发现已经解释过了。顺便说一句,我使用的是python 3.8