news 2026/5/15 19:19:21

python之Starlete的lifespan使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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确保资源释放。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 5:32:25

Procyon终极指南:快速掌握Java反编译与元编程工具

Procyon终极指南:快速掌握Java反编译与元编程工具 【免费下载链接】procyon Procyon is a suite of Java metaprogramming tools, including a rich reflection API, a LINQ-inspired expression tree API for runtime code generation, and a Java decompiler. 项…

作者头像 李华
网站建设 2026/5/9 9:03:49

如何充分利用Screenbox播放器?终极完整使用指南大揭秘

Screenbox播放器作为Windows平台上一款基于LibVLC引擎的现代化媒体播放解决方案,以其卓越的性能表现和优雅的设计理念,正在重新定义用户对视频播放体验的认知。这款免费开源工具不仅支持Windows 10 1903及以上版本,还完美兼容Windows 11和Xbo…

作者头像 李华
网站建设 2026/5/11 16:30:38

Simple Live:重新定义跨平台直播观看体验

Simple Live:重新定义跨平台直播观看体验 【免费下载链接】dart_simple_live 简简单单的看直播 项目地址: https://gitcode.com/GitHub_Trending/da/dart_simple_live 你是否曾为同时关注多个平台的主播而烦恼?是否希望有一个统一的入口来管理所有…

作者头像 李华
网站建设 2026/5/12 16:19:26

Steam Economy Enhancer:终极免费Steam市场与库存管理工具

Steam Economy Enhancer:终极免费Steam市场与库存管理工具 【免费下载链接】Steam-Economy-Enhancer 中文版:Enhances the Steam Inventory and Steam Market. 项目地址: https://gitcode.com/gh_mirrors/ste/Steam-Economy-Enhancer 还在为繁琐的…

作者头像 李华
网站建设 2026/5/14 5:13:50

WeakAuras伴侣使用全攻略:告别繁琐手动更新

WeakAuras伴侣使用全攻略:告别繁琐手动更新 【免费下载链接】WeakAuras-Companion A cross-platform application built to provide the missing link between Wago.io and World of Warcraft 项目地址: https://gitcode.com/gh_mirrors/we/WeakAuras-Companion …

作者头像 李华
网站建设 2026/5/5 7:45:24

B站API完整指南:Python异步爬虫快速入门教程

B站API完整指南:Python异步爬虫快速入门教程 【免费下载链接】bilibili-api 哔哩哔哩常用API调用。支持视频、番剧、用户、频道、音频等功能。原仓库地址:https://github.com/MoyuScript/bilibili-api 项目地址: https://gitcode.com/gh_mirrors/bi/bi…

作者头像 李华