Flask中导入变量为何每次请求重求值?全局变量如何持久化?
问题
我正在开发一个Flask应用,app.py文件中导入了外部变量:
from other_file import rnd @app.route('/some/path/', methods=['GET']) def some_func(): return make_response(jsonify(value=str(rnd)))
other_file.py内容如下:
import random rnd = random.randint(100000, 1000000)
每次请求时,接口返回的rnd值都不同,请问原因是什么?我希望每次请求返回相同的rnd值。
另外,若我想存储应用级全局数据,比如定义:
logged_in_users_list = []
该列表会在每次请求后被清空吗?
实际上我在FastAPI应用中使用类似方式,变量能正常保留列表内容,二者差异是什么?
1. rnd每次请求值不同的原因及解决方法
原因在于Flask的运行进程模型:
当你用默认的flask run启动开发服务器时,debug模式默认开启,会启动多个进程(通常2个)。每个进程启动时都会重新导入other_file.py,而rnd = random.randint(...)是在模块导入阶段执行的,所以每个进程会生成独立的随机数。请求被分发到不同进程时,就会返回不同的值。即使关闭debug模式,如果生产环境用多worker的服务器(比如Gunicorn),同样会出现这个问题。
要让rnd值全局固定,有两种可靠方案:
- 将随机数生成移到应用初始化阶段,确保只执行一次:
# app.py from flask import Flask, make_response, jsonify import random app = Flask(__name__) # 应用启动时生成一次随机数,存在配置中 app.config['FIXED_RND'] = random.randint(100000, 1000000) @app.route('/some/path/', methods=['GET']) def some_func(): return make_response(jsonify(value=str(app.config['FIXED_RND']))) - 修改
other_file.py,用懒加载确保随机数只生成一次:
然后在# other_file.py import random _rnd = None def get_rnd(): global _rnd if _rnd is None: _rnd = random.randint(100000, 1000000) return _rndapp.py中调用函数而非直接导入变量:from other_file import get_rnd @app.route('/some/path/', methods=['GET']) def some_func(): return make_response(jsonify(value=str(get_rnd())))
2. 全局列表logged_in_users_list会被清空吗?
不一定,取决于服务器的运行模式:
- 单进程单线程模式(比如关闭debug的Flask开发服务器、单worker的Gunicorn):所有请求共享同一个进程的内存空间,列表内容会持续保留,不会被清空。
- 多进程模式(比如debug模式的Flask开发服务器、多worker的生产服务器):每个进程有独立的内存空间,列表只在当前进程内有效。当请求被分发到不同进程时,会看到不同的列表状态,看起来像是被清空,但实际上是每个进程有自己的列表副本。
3. Flask与FastAPI的全局变量表现差异
核心差异是默认开发服务器的进程配置:
- Flask默认开发服务器(
flask run)在debug模式下自动启用多进程,每个进程都会重新加载模块,导致全局变量被重复初始化;即使关闭debug,默认是单进程,但开发者常习惯开debug开发,所以容易遇到变量不共享的问题。 - FastAPI默认开发服务器(
uvicorn main:app)默认是单进程单线程(除非手动指定--workers参数),所有请求共享同一进程内存,全局变量内容可以正常保留。
另外需要注意:无论Flask还是FastAPI,都不推荐用全局变量存储应用级状态(比如登录用户列表),因为多进程/分布式部署下必然会出现状态不一致的问题,更可靠的方案是用Redis、数据库等外部存储来共享状态。
内容的提问来源于stack exchange,提问作者Yusif
相关产品推荐
相关产品推荐

