简体   繁体   English

Python 3.10 asyncio.gather() 显示 DeprecationWarning: 没有当前事件循环

[英]Python 3.10 asyncio.gather() shows DeprecationWarning: There is no current event loop

I have a Django app and in one of its views I use asyncio in order to make some concurent requests to an external component.我有一个 Django 应用程序,在它的一个视图中,我使用 asyncio 来向外部组件发出一些并发请求。

Here is the idea:这是想法:

import asyncio


async def do_request(project):
    result = ...

    return result

def aggregate_results(projects: list):
    loop = asyncio.new_event_loop()

    asyncio.set_event_loop(loop)

    results = loop.run_until_complete(
        asyncio.gather(*(do_request(project) for project in projects))
    )

    loop.close()

    return zip(projects, results)

Well, when I run the tests I get DeprecationWarning: There is no current event loop at this line:好吧,当我运行测试时,我得到了DeprecationWarning: There is no current event loop at this line:

        asyncio.gather(*(do_request(project) for project in projects))

How should I interpret this warning and what do I need to change to get rid of it?我应该如何解释这个警告,我需要改变什么来摆脱它? Thanks!谢谢!

According to the documentation , this happens because there is no event loop running at the time when you call gather .根据文档,发生这种情况是因为在您调用gather没有运行事件循环。

Deprecated since version 3.10: Deprecation warning is emitted if no positional arguments are provided or not all positional arguments are Future-like objects and there is no running event loop. 3.10 版后已弃用:如果未提供位置 arguments 或并非所有位置 arguments 都是类似未来的对象并且没有正在运行的事件循环,则会发出弃用警告。

As you've probably noticed, your code works.您可能已经注意到,您的代码有效。 It will continue to work and you can ignore the deprecation warning as long as you use 3.10.它将继续工作,只要您使用 3.10,您就可以忽略弃用警告。 At some point in the future, though, this may change to a runtime error.但是,在将来的某个时候,这可能会变成运行时错误。

If you'll bear with me a moment, the recommended way to run an event loop is with run , not loop.run_until_complete .如果你能忍受我一会儿, 运行事件循环的推荐方法是使用run ,而不是loop.run_until_complete

def aggregate_results(projects: list):
    results = asyncio.run(asyncio.gather(*(do_request(project) for project in projects)))
    return zip(projects, results)

This, however, won't actually work.然而,这实际上是行不通的。 You'll instead get an exception你会得到一个例外

ValueError: a coroutine was expected, got <_GatheringFuture pending>

The fix is to instead await gather from another coroutine.解决方法是等待来自另一个协程的gather

async def get_project_results(projects: list):
    results = await asyncio.gather(*(do_request(project) for project in projects))
    return results

def aggregate_results(projects: list):
    results = asyncio.run(get_project_results(projects))
    return zip(projects, results)

(You could also use get_project_results with your version of aggregate_results .) (您也可以将get_project_results与您的aggregate_results版本一起使用。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM