FastAPI 如何仅初始化一次全局变量供所有API请求全程调用
问题根因
你遇到的init_data执行两次的问题,根源是Uvicorn的启动逻辑:
- 你在
if __name__ == '__main__'块中调用uvicorn.run时传入的是字符串example_trouble:app,Uvicorn会重新导入一次example_trouble模块,此时模块顶层的data = init_data('path')代码会第二次执行 - 第一次执行是你直接运行脚本时,脚本作为
__main__模块执行的顶层代码
FastAPI官方通用实现方案
FastAPI推荐使用启动事件完成全局资源的一次性初始化,这类逻辑会在服务启动完成前仅执行一次,初始化后的变量可以被所有请求全局调用,完全符合你的需求。
调整后代码示例
from fastapi import FastAPI import uvicorn app = FastAPI() # 定义全局变量占位 data = {} def init_data(path): print("init call") data = {} data[1] = "123" data[2] = "abc" return data # 注册启动事件,服务启动时仅执行一次 @app.on_event("startup") def startup_event(): global data data = init_data('path') @app.get('/') def example_method(): return {'Data': data[1]} if __name__ == '__main__': uvicorn.run(app, host='localhost', port=8000)
轻量替代方案
如果你不想调整代码结构,也可以直接修改Uvicorn启动参数:把uvicorn.run(f'example_trouble:app', ...)修改为uvicorn.run(app, ...),直接传递app对象而不是字符串导入路径,就能避免模块被重复导入,也不会出现init_data执行两次的问题。
注意事项
如果你使用多worker启动Uvicorn,每个worker进程会各自执行一次初始化逻辑,这是进程隔离的正常表现,如果你需要所有worker共享同一份数据,需要额外引入Redis之类的共享存储组件。
内容的提问来源于stack exchange,提问作者Alexander Lipatov
相关产品推荐
相关产品推荐

