未调用asyncio.set_event_loop的后果及该方法的作用是什么?
asyncio.set_event_loop的作用与不调用的后果
不调用set_event_loop的影响
你的测试代码里直接用loop.run_until_complete(test1())没出问题,是因为你全程直接操作自己创建的loop对象,没依赖线程的默认事件循环。但如果代码里有需要获取当前线程默认循环的逻辑,就会出问题:
- 调用
asyncio.get_running_loop()时,会直接抛出RuntimeError: no running event loop; - 用
asyncio.create_task()不带loop参数时,也会因为找不到默认循环而报错; - 一些第三方异步库内部可能会自动调用
get_running_loop(),这时程序会直接崩掉。
asyncio.set_event_loop到底干嘛用
它的核心就是给当前OS线程绑定一个“默认事件循环”,让后续在这个线程里的异步代码不用每次都传loop对象,能自动用上这个绑定好的循环:
- 调用
asyncio.get_running_loop()时,会返回这个绑定的循环(只要循环已经启动); - 用
asyncio.create_task()创建任务时,会自动把任务加到这个默认循环里; - 第三方异步库依赖默认循环时,也能正常工作。
对比看差异
不调用set_event_loop(报错示例)
import asyncio async def test2(): # 尝试获取默认循环,此时没绑定,直接报错 loop = asyncio.get_running_loop() print(loop) loop = asyncio.new_event_loop() loop.run_until_complete(test2())
运行这段代码会直接抛出RuntimeError,因为get_running_loop()找不到当前线程的默认循环。
调用set_event_loop(正常示例)
import asyncio async def test2(): loop = asyncio.get_running_loop() print(loop) # 能正常输出绑定的loop对象 loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) # 把loop绑定到当前线程 loop.run_until_complete(test2())
这段代码就能正常运行,因为set_event_loop已经把你创建的loop设为当前线程的默认循环了。
总结一下
- 如果你全程自己拿着loop对象操作(比如只用
loop.run_until_complete()、loop.create_task()),不调用set_event_loop完全没影响; - 但只要代码里有依赖默认事件循环的逻辑,就必须先调用
set_event_loop绑定,不然会出现各种找不到循环的错误。
内容的提问来源于stack exchange,提问作者Avadx FeIRM
相关产品推荐
相关产品推荐

