如何为aiohttp v3设置特定事件循环?原v2.3方法已失效
解决aiohttp v3+中设置自定义事件循环的高层级方案
嘿,我之前升级aiohttp的时候也遇到过这个困惑!v3版本确实移除了aiohttp.web.run_app的loop参数,而且Application的loop参数也早就被标记为弃用了,官方是想引导我们用更贴合asyncio现代设计的方式来处理事件循环。不过如果你确实需要指定自定义循环,完全不用退回到make_handler这种底层API,这里有两个高层级的解决方案:
方法一:提前设置当前线程的默认事件循环
run_app内部会调用asyncio.get_event_loop()来获取事件循环,所以我们只需要在调用它之前,把自定义循环设为当前线程的默认循环即可,代码示例如下:
import asyncio from aiohttp import web # 创建你需要的自定义事件循环 custom_loop = asyncio.new_event_loop() # 将其设置为当前线程的默认循环 asyncio.set_event_loop(custom_loop) # 定义路由和请求处理函数 async def hello(request): return web.Response(text="Hello, custom loop!") app = web.Application() app.add_routes([web.get('/', hello)]) # 直接调用run_app,它会自动使用我们设置好的默认循环 web.run_app(app)
方法二:使用AppRunner+TCPSite手动管理应用生命周期(推荐)
aiohttp v3引入了AppRunner和TCPSite这些高层级API,用来更灵活地管理应用的启动、运行和关闭。这种方式能让你完全掌控事件循环的使用,代码示例:
import asyncio from aiohttp import web async def hello(request): return web.Response(text="Hello from controlled loop!") async def run_app_with_custom_loop(): app = web.Application() app.add_routes([web.get('/', hello)]) # 创建AppRunner并初始化 runner = web.AppRunner(app) await runner.setup() # 创建站点并绑定地址端口 site = web.TCPSite(runner, 'localhost', 8080) await site.start() # 让应用保持运行,直到收到停止信号(比如Ctrl+C) await asyncio.Event().wait() # 初始化自定义循环并运行应用 custom_loop = asyncio.new_event_loop() try: custom_loop.run_until_complete(run_app_with_custom_loop()) finally: # 确保循环被正确关闭 custom_loop.close()
关于弃用loop参数的小说明
官方弃用显式传递loop参数,是为了跟上asyncio的演进——从Python 3.7开始,asyncio推荐使用asyncio.run()这种自动管理循环的方式,减少手动传递循环的冗余代码。但如果你的业务场景必须自定义循环(比如要设置特定的循环策略),上面两种方法都能满足需求,而且都是官方推荐的高层级用法,完全不用碰底层的make_handler。
内容的提问来源于stack exchange,提问作者SangminKim
相关产品推荐
相关产品推荐

