Flask 2.3 移除 before_first_request 等旧函数,因其在多进程下不可靠且违背“显式优于隐式”原则;escape 和 JSONEncoder 改由 markupsafe 和 DefaultJSONProvider 提供,要求开发者明确依赖与初始化逻辑。

因为 Flask 2.3 不再为向后兼容而牺牲架构清晰性——它主动移除了那些语义模糊、易被误用、且已有现代替代方案的旧函数,比如 app.json_encoder、before_first_request、escape(从 flask 导入)、JSONEncoder(从 flask.json 导入)等。
为什么 before_first_request 被删?不是“不好用”,而是“不可靠”
这个装饰器在多进程部署(如 gunicorn 多 worker)下根本无法保证“只执行一次”。每个 worker 进程都会独立触发它,导致数据库初始化重复、缓存预热冲突、甚至连接池爆满。Flask 团队明确指出:这不是 bug,是设计缺陷。
- 错误现象:
AttributeError: 'Flask' object has no attribute 'before_first_request' - 真实场景:你本地单进程跑着没问题,一上生产就报错或数据异常
- 替代做法:用 CLI 命令显式初始化(
flask init-db),或在应用启动时用with app.app_context(): db.create_all()手动触发 - 关键点:不是让你“换个写法”,而是逼你把初始化逻辑从请求生命周期里抽出来,放到可控的、可测试的入口点
escape 和 JSONEncoder 为什么不能直接 import?
它们没消失,只是挪了地方——Flask 不再“打包”第三方库的 API,而是要求你直连源头。比如 escape 现在必须从 markupsafe 导入;JSONEncoder 已被 DefaultJSONProvider 取代,且必须通过 app.json 注册。
- 旧写法报错:
from flask import escape→ImportError - 新写法:
from markupsafe import escape(注意大小写) -
JSONEncoder替代方案:继承flask.json.provider.DefaultJSONProvider,重写default()方法,再赋给app.json.provider_class - 容易踩坑:仍用
app.json_encoder = CustomEncoder会静默失效——该属性已彻底删除,不报错但也不生效
删除这些函数,对性能或功能有实际影响吗?
几乎没有。它们本身不参与请求处理主干,删掉后框架启动更快、导入更干净、依赖链更短。真正受影响的是“写法惯性”:你习惯了靠装饰器自动触发、靠全局配置隐式生效,而 Flask 2.3+ 要求你把每一步都写明白。
立即学习“Python免费学习笔记(深入)”;
- 比如
send_file不再猜 MIME 类型,必须显式传mimetype或attachment_filename,否则直接抛ValueError -
app.got_first_request被弃用,意味着你不能再靠它做条件判断——得自己维护状态标志或改用信号(signals) - 所有移除项都已在 2.2 版本中标记为
DeprecationWarning,升级前跑一遍python -W default::DeprecationWarning your_app.py就能提前发现
最常被忽略的细节是:这些删除不是孤立动作,而是整套“显式优于隐式”原则的落地。你改的不是几行 import,而是整个初始化和扩展注册的思维模式。


















