如果在列表理解中调用函数,为什么我只得到一个“RuntimeWarning”

问题描述 投票:0回答:1

如果我取消注释第一个示例的行,我只会得到一个运行时警告,如下所示:


C:\Users\marat\AppData\Local\Programs\Python\Python312\Lib\asyncio\events.py:88: RuntimeWarning: coroutine 'some_async_func' was never awaited
  self._context.run(self._callback, *self._args)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

如果我取消注释第二个示例的行,我会收到四个具有相同文本的运行时警告。

为什么在第一个例子中我只收到一个警告,而在第二个例子中,如果在这两种情况下我创建了四个协程

,我会收到四个警告
import asyncio


async def some_async_func():
    await asyncio.sleep(1)


async def main() -> None:
    pass
    
    # FIRST EXAMPLE. 
    # coros = [some_async_func() for _ in range(4)]  # If i uncommment this i get ONE warning
    
    # SECOND EXAMPLE
    # z = some_async_func()  # If i uncommment these 4 lines, i get FOUR warnings  
    # z = some_async_func()
    # z = some_async_func()
    # z = some_async_func()


if __name__ == '__main__':
    asyncio.run(main())

此外,如果取消注释两个示例,我会收到四个警告不是五个

python版本:3.12.8

python python-asyncio warnings
1个回答
0
投票

默认警告模式是“一次”——这意味着它只会对特定调用站点发出一次警告

在理解中,您有一个调用站点(被多次调用)

在非理解版本中,您有四个单独的调用点,因此您会收到四个(实际上是 3 个,见下文)单独的警告

“关闭一”的怪癖是由于警告的引发方式造成的——只有当协程的引用计数降到零时才会引发警告(没有等待)——如果您在之后添加

z = None
你的代码或多或少会得到你所期望的(较长的答案与 python 进程如何被拆除以及最后一个分配何时被垃圾收集有关)

请注意,根据 python 版本,输出有点令人困惑,因为每个协程还会收到两个警告(因为系统建议您使用

tracemalloc
来找出原始调用者):

$ python t.py
C:\Users\asott\t.py:16: RuntimeWarning: coroutine 'some_async_func' was never awaited
  z = some_async_func()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
C:\Users\asott\t.py:17: RuntimeWarning: coroutine 'some_async_func' was never awaited
  z = some_async_func()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
C:\Users\asott\t.py:18: RuntimeWarning: coroutine 'some_async_func' was never awaited
  z = some_async_func()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
C:\Python312\Lib\asyncio\events.py:88: RuntimeWarning: coroutine 'some_async_func' was never awaited
  self._context.run(self._callback, *self._args)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
© www.soinside.com 2019 - 2024. All rights reserved.