如何抑制“协程从未等待”警告?

Eke*_*voo 9 python python-asyncio

所有关于“coroutine was never waiting”的搜索结果都是针对那些要么试图“即发即忘”,要么实际上忘记等待的人。这不是我的情况。

我想像经常使用生成器一样使用协程:我在这里创建它,同时我手头有所有变量,但我不确定是否需要运行它。就像是:

options = {
   'a': async_func_1(..., ...),
   'b': async_func_2(),
   'c': async_func_3(...),
}
Run Code Online (Sandbox Code Playgroud)

和其他地方:

appropriate_option = figure_the_option_out(...)
result = await options[appropriate_option]
Run Code Online (Sandbox Code Playgroud)

Eke*_*voo 9

我仍然没有找到可以在初始化时完成的事情,但我找到了一个可以在等待所有协程之后完成的解决方案。

for coroutine in options.values():
    coroutine.close()
Run Code Online (Sandbox Code Playgroud)

close()函数适用于所有协程,无论是否等待。

  • 不知道为什么这被否决了 - 这是我认为正确的方式。即使不等待也可以调用“coroutine.close()”,它记录在此处:https://docs.python.org/3/reference/datamodel.html#coroutine-objects (4认同)

Ian*_*dby 4

deceze的评论是,在准备好等待协程对象之前,不应创建协程对象,这可能是最理想的解决方案。

但如果这不切实际,您可以在垃圾收集之前weakref.finalize()调用协程对象的方法。close()

>python -m asyncio
asyncio REPL 3.9.5 (default, May 18 2021, 14:42:02) [MSC v.1916 64 bit (AMD64)] on win32
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> import weakref
>>> async def coro(x):
...     print(x)
...
>>> coro_obj = coro('Hello')
>>> del coro_obj
<console>:1: RuntimeWarning: coroutine 'coro' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
>>> coro_obj = coro('Hello')
>>> _ = weakref.finalize(coro_obj, coro_obj.close)
>>> del coro_obj
>>>
Run Code Online (Sandbox Code Playgroud)