【问题标题】:How to suppress "coroutine was never awaited" warning?如何抑制“从未等待协程”警告?
【发布时间】:2020-05-27 14:20:00
【问题描述】:

所有关于“coroutine was never awaited”的搜索结果都是针对那些试图即发即弃或确实忘记等待的人。这不是我的情况。

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

options = {
   'a': async_func_1(..., ...),
   'b': async_func_2(),
   'c': async_func_3(...),
}

和其他地方:

appropriate_option = figure_the_option_out(...)
result = await options[appropriate_option]

【问题讨论】:

  • 怎么办'a': lambda: async_func_1(..., ...)等,然后result = await options[appropriate_option]()
  • 他说了什么。你正在创建你永远不会等待的协程。你不应该那样做。如果您真的打算等待,请仅致电 async_func_*,而不仅仅是填写您的字典。
  • 我为什么不应该这样做?创建协程的成本是多少?
  • 不是不应该做(只有你才能真正回答这个问题),而是不应该必须去做。我认为您正在尝试“提高性能”?做这样的抢先优化可以获得多少性能?如果你收获很多,那就去做,否则就是浪费。
  • 我真的在尝试优化 IDE 和调试工具,通过仅消除我知道不适用的特定警告来帮助我避免错误。在这种特殊情况下,我阅读了警告并且我知道没关系,所以我只想安抚这种特殊情况的警告。

标签: python python-asyncio


【解决方案1】:

这可能会有所帮助


import warnings

...

    def go(self):
        try:
            self.loop.run_until_complete(self.run())
        except Exception as e:
            print(f"  {e}")
        finally:
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")
                self._clean_up()

...

self._clean_up() 导致 RuntimeWarning 的位置

您可以像上面那样暂时禁止警告。您可以在https://python.readthedocs.io/en/latest/library/warnings.html#temporarily-suppressing-warnings

上阅读更多详细信息

【讨论】:

    【解决方案2】:

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

    for coroutine in options.values():
        coroutine.close()
    

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

    【讨论】:

    【解决方案3】:

    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
    >>>
    

    【讨论】:

      【解决方案4】:

      您可以通过在 Python 中使用 -W 标志来抑制警告。

      python -W ignore my_script.py
      

      【讨论】:

      • 这将抑制所有警告,包括有用的警告
      猜你喜欢
      • 2015-04-20
      • 1970-01-01
      • 2018-10-26
      • 1970-01-01
      • 2019-12-19
      • 1970-01-01
      • 2021-10-22
      • 2019-12-15
      • 2021-10-15
      相关资源
      最近更新 更多