bigywater.tech
Flask · 54

Context Processor

模板里为什么不用传 request 和 g 就能用?想让所有模板都有一个变量怎么写?处理器什么时候执行、执行几次?放太多会不会拖慢页面?这篇逐项实测。

每次渲染 1 次
上下文处理器的执行频率(与模板用不用变量无关)
后注册的赢
多个处理器返回同名变量时的覆盖规则
7889 µs
10 个各睡 0.5 ms 的处理器下一次渲染的耗时

默认注入的变量

实测 · 本机执行输出
  GET /defaults → config=Config|request=/defaults|session=SecureCookieSession|g=_AppCtxGlobals|url_for=/defaults|flashed=0
  update_template_context 往空字典里放了: ['bp_global', 'g', 'now_called', 'request', 'site_name', 'util']
  Flask 自带的上下文处理器: ['_default_template_ctx_processor'] + 你注册的 3 个

上一篇:模板继承与 Block;下一篇:自定义 Template Filter。全局函数与它的区别见自定义 Template Global。

自己的处理器与覆盖规则

实测 · 本机执行输出
  site_name = 视图里传的 (视图里显式传的优先于处理器)
  不传时的 site_name: render_template_string → 被第二个覆盖

执行频率

实测 · 本机执行输出
  渲染 3 次后处理器被调用了 3 次
  一次渲染里用 5 次变量,处理器只调用 1 次

蓝图的处理器

实测 · 本机执行输出
  GET /b/t(蓝图的视图)→ blueprint 的变量|bp 注册的全局变量
  GET /t(应用的视图)→ 无|bp 注册的全局变量

惰性函数

实测 · 本机执行输出
  渲染 3 次「没用到变量」的页面:eager 处理器执行 3 次(无论用不用都算);lazy 的函数执行 0 次
  再渲染 1 次「用到 l_value()」的页面:lazy 函数执行 1 次

耗时

实测 · 本机执行输出
  0 个处理器                   每个请求 180 µs
  10 个空处理器                 每个请求 186 µs
  10 个各 0.5 ms 的处理器        每个请求 7889 µs

分步演示

上下文处理器
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动
    • 没有验证:异步视图里的处理器、处理器里访问数据库的事务边界、{% include %} 与 {% import %} 是否重新调用处理器(本篇只验证了单个模板的调用次数)、Flask-Login 的 current_user 是怎么通过处理器注入的
    京ICP备2026067502号-1京公网安备11010502063487号