You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:08:04