Asyncio:从未检索到任务异常的奇怪之处

Asyncio: Weirdness of Task exception was never retrieved

假设我有一个简单的代码:

import asyncio


async def exc():
    print(1 / 0)


loop = asyncio.get_event_loop()

loop.create_task(exc())

try:
    loop.run_forever()
except KeyboardInterrupt:
    loop.stop()
    loop.close()

如果我 运行 它,我会立即收到错误消息

Task exception was never retrieved
future: <Task finished coro=<exc() done, defined at qq.py:4> exception=ZeroDivisionError('division by zero',)>
Traceback (most recent call last):
  File "qq.py", line 5, in exc
    print(1 / 0)
ZeroDivisionError: division by zero

但是,如果我将 loop.create_task(exc()) 更改为 task = loop.create_task(exc())

单击 ctrl+c 后我会收到相同的错误消息

为什么任务分配会改变错误输出的时间?

可以使用 Future.exception() 检索任务中的异常(准确地说是底层 asyncio.Future)。如果未检索到,将在使用事件循环的 call_exception_handler.

释放 Future 对象时处理异常

因此,正如@dirn 指出的那样,虽然任务具有引用(在您的情况下已分配给变量),但它不会被释放,因此不会调用 del task_future,也不会执行循环的处理程序要么。