当前位置: 首页 > news >正文

python之Starlete的lifespan使用

一、lifespan 是什么?

lifespan是 Starlette 提供的应用生命周期管理机制,用于定义应用启动(startup)和关闭(shutdown)时需要执行的操作,比如:

  • 启动时:初始化数据库连接池、加载配置文件、启动定时任务、创建缓存实例;
  • 关闭时:关闭数据库连接、释放资源、保存临时数据、停止定时任务。

它替代了 Starlette 旧版本中的on_startup/on_shutdown钩子,是当前推荐的生命周期管理方式(更符合 ASGI 规范)。

二、核心使用方式

Starlette 的lifespan支持两种写法:装饰器写法(简单场景)和上下文管理器写法(复杂场景),下面分别演示。

前置准备

先安装依赖(确保 Starlette 版本 ≥ 0.25.0,推荐最新版):

pipinstallstarlette uvicorn
1. 装饰器写法(推荐新手)

适合启动/关闭逻辑简单、无需共享状态的场景,用@app.lifespan装饰异步函数,函数返回{"startup": 启动函数, "shutdown": 关闭函数}

fromstarlette.applicationsimportStarlettefromstarlette.responsesimportJSONResponseimportasyncio# 创建应用实例app=Starlette(debug=True)# ---------------------- 生命周期函数 ----------------------# 启动时执行asyncdefstartup_event():print("🚀 应用启动中...")# 模拟初始化数据库连接池awaitasyncio.sleep(1)# 模拟异步操作app.state.db="已初始化的数据库连接池"# 把资源存在app.state中,供视图使用print("✅ 应用启动完成(数据库连接已初始化)")# 关闭时执行asyncdefshutdown_event():print("🔌 应用关闭中...")# 模拟关闭数据库连接awaitasyncio.sleep(1)app.state.db=None# 释放资源print("❌ 应用关闭完成(数据库连接已释放)")# 注册生命周期钩子@app.lifespanasyncdeflifespan_manager(_):return{"startup":startup_event,"shutdown":shutdown_event}# ---------------------- 普通视图 ----------------------@app.route("/")asyncdefhomepage(request):# 从app.state获取生命周期中初始化的资源db_status="已连接"ifrequest.app.state.dbelse"未连接"returnJSONResponse({"message":"Hello Starlette","db_status":db_status})

运行命令:

uvicorn main:app --reload

运行效果

  • 启动时控制台输出:🚀 应用启动中...✅ 应用启动完成
  • 访问http://127.0.0.1:8000,返回{"message":"Hello Starlette","db_status":"已连接"}
  • 停止应用(按 Ctrl+C)时,控制台输出:🔌 应用关闭中...❌ 应用关闭完成
2. 上下文管理器写法(进阶)

适合需要更精细控制生命周期、或启动/关闭逻辑有依赖关系的场景(比如启动时创建的资源需要在关闭时显式清理),通过async with实现。

fromstarlette.applicationsimportStarlettefromstarlette.responsesimportJSONResponseimportasyncio app=Starlette(debug=True)# 上下文管理器风格的lifespan@app.lifespanasyncdeflifespan_manager(app):# ---------------------- 启动阶段(async with 进入时) ----------------------print("🚀 应用启动中(上下文管理器版)...")# 初始化资源app.state.redis="已初始化的Redis连接"awaitasyncio.sleep(1)print("✅ 启动完成(Redis已连接)")yield# 核心:yield 之前是启动逻辑,之后是关闭逻辑# ---------------------- 关闭阶段(async with 退出时) ----------------------print("🔌 应用关闭中(上下文管理器版)...")# 释放资源app.state.redis=Noneawaitasyncio.sleep(1)print("❌ 关闭完成(Redis已断开)")@app.route("/redis")asyncdefredis_status(request):redis_status="已连接"ifrequest.app.state.rediselse"未连接"returnJSONResponse({"message":"Redis状态","redis_status":redis_status})

核心特点

  • yield是分界点:代码执行到yield时,应用开始接收请求;
  • 应用关闭时,会执行yield之后的代码,确保资源被正确清理;
  • 这种写法更符合 Python 上下文管理器的习惯,也支持异常处理(比如在try/finally中包裹逻辑)。
3. 独立定义 lifespan(解耦写法)

如果生命周期逻辑复杂,可把lifespan抽成独立函数,再传给Starlette构造函数,代码更整洁:

fromstarlette.applicationsimportStarlettefromstarlette.responsesimportJSONResponse# 独立的lifespan函数asyncdefcustom_lifespan(app):# 启动逻辑app.state.config={"env":"dev","port":8000}yield# 关闭逻辑app.state.config=None# 创建应用时指定lifespanapp=Starlette(debug=True,lifespan=custom_lifespan,# 传入独立的lifespanroutes=[app.route("/config")(lambdarequest:JSONResponse(request.app.state.config))])

三、关键注意事项

  1. app.state的使用
    • 生命周期中初始化的资源(如数据库连接、配置),建议存在app.state中,视图函数可通过request.app.state访问;
    • app.state是全局的,多个请求共享,需注意异步安全(比如数据库连接池本身是异步安全的)。
  2. 必须是异步函数
    • lifespan及内部的启动/关闭函数都必须用async def定义,不能用同步函数;
    • 如果需要执行同步阻塞操作(比如加载本地大文件),建议用asyncio.to_thread包装,避免阻塞事件循环。
  3. 异常处理
    • 启动阶段如果抛出异常,应用会直接退出,不会接收请求;
    • 可在lifespan中加try/except捕获异常,比如:
      @app.lifespanasyncdeflifespan_manager(app):try:# 启动逻辑app.state.db=awaitinit_db()yieldexceptExceptionase:print(f"启动失败:{e}")raise# 重新抛出异常,让应用退出finally:# 关闭逻辑(无论是否异常都会执行)ifapp.state.db:awaitapp.state.db.close()

总结

  1. Starlette 的lifespan是管理应用启动/关闭生命周期的核心机制,替代了旧的on_startup/on_shutdown
  2. 常用两种写法:装饰器写法(简单场景)和上下文管理器写法(进阶/复杂场景),核心是通过app.state共享初始化的资源;
  3. lifespan函数必须是异步的,启动阶段异常会导致应用退出,关闭阶段建议通过finally确保资源释放。
http://www.gsyq.cn/news/146564.html

相关文章:

  • 深度剖析北京顺义遗嘱咨询律所哪家好:2025-2026专业实力与客户反馈全解 - 老周说教育
  • Procyon终极指南:快速掌握Java反编译与元编程工具
  • Screenbox媒体播放器:打造Windows平台极致多媒体体验
  • 如何从零掌握CS2游戏辅助开发:终极框架技术实战指南
  • 深入解析:【行测】判断推理秒杀技巧
  • 工业3D相机常见参数及分类的通用术语解读
  • 2025年合肥公寓出租/写字楼出租/办公室出租/园区推荐前十榜单:安徽广电文创产业园管理有限公司领衔 - 2025年品牌推荐榜
  • 2025-2026无锡短视频运营公司权威推荐,复购率TOP榜与精准获客方案指南 - 品牌鉴赏师
  • HarmonyOS开发之分布式硬件共享——使用虚拟设备
  • 如何充分利用Screenbox播放器?终极完整使用指南大揭秘
  • 【值得收藏】大模型微调技术:让你的AI模型适应特定任务的完整指南
  • 2025抗衰老的保健品十大品牌清单:抗衰老哪个产品好?真实用户反馈大汇总 - 博客万
  • 什么是IPD咨询?解码企业高效研发的核心密码
  • 陕西省安康市自建房设计公司哪家强?2025最新评测排行榜+5星企业推荐 - 苏木2025
  • 2026年京东e卡回收哪里最划算?三大渠道深度解析 - 京顺回收
  • 频域Transformer:突破图像去模糊技术瓶颈的智能解决方案
  • HarmonyOS开发之多端协同案例——分布式购物车
  • APatch深度解析:如何实现Android内核级系统定制与模块化开发
  • 赋能业务:低代码与高易用性数据中台厂商盘点
  • 终极解决方案:如何用HomeAssistant-GreeClimateComponent实现智能空调控制
  • GPT-SoVITS语音合成在太空站失重环境下的人机沟通适应性
  • 安阳口碑好的蘑菇石厂家盘点,2025年最新排名揭晓!蘑菇石/脚踏石/冰裂纹/贴墙石/石材/文化石/天然石/地铺石/碎拼石蘑菇石品牌推荐榜单 - 品牌推荐师
  • 陕西省汉中市自建房评测排行榜:6家主流企业实地测评,哪家更谱? - 苏木2025
  • yield处理100万行CSV数据导入必须使用cli模式吗?
  • 跟着本地人吃就对了!2025年度十大高口碑火锅品牌排行,烧菜火锅/老火锅/特色美食/火锅店/火锅/美食/社区火锅火锅回头客多的选哪家 - 品牌推荐师
  • 如何解锁IDM完整功能:使用指南
  • 想在丰南区老家农村盖房子,靠谱的自建房公司口碑推荐。河北唐山丰南区自建房公司/机构权威测评推荐排行榜 - 苏木2025
  • 【大模型部署新突破】:Open-AutoGLM一键部署脚本详解与优化策略
  • 2025年12月阿里巴巴国际站代运营,阿里巴巴数据分析代运营,1688代运营公司优选,实战效果与合作模式深度指南! - 品牌鉴赏师
  • 百度LAC中文分词工具:让中文文本处理变得如此简单