Flask应用实例化时调用Flask(__name__)会初始化配置、blueprints、extensions及Jinja环境,但模板加载延迟至首次请求;__name__用于路径定位而非身份标识,多实例需端口或WSGI分流;@app.route()仅注册路由不执行函数,匹配与调用均在请求上下文中完成。

Flask 没有“核心原理第226讲”这种官方分讲体系,所谓“第226讲”是营销包装,实际学习应聚焦真实机制:请求生命周期、应用对象初始化、Werkzeug 底层协作方式。
Flask 应用实例化时到底发生了什么
调用 Flask(__name__) 不只是创建一个类实例,它会立即设置 self.name、加载配置默认值、初始化 self.blueprints 和 self.extensions 空字典,并绑定 self.jinja_env —— 但此时模板文件尚未加载,render_template 要等第一次请求才触发环境构建。
-
__name__主要用于定位静态文件和模板的相对路径,不是用来“识别应用身份”的 ID - 若传入字符串(如
Flask("myapp")),则必须手动设置app.root_path,否则send_static_file会报RuntimeError: No root path can be established - 多个
Flask()实例共存不冲突,但共享同一个werkzeug.serving.make_server进程时,需确保它们监听不同端口或用 WSGI 中间件分流
为什么 @app.route() 注册的函数不立刻执行
装饰器 @app.route() 本质是把视图函数注册进 app.url_map(一个 Map 对象),而非绑定到某个运行时上下文。路由匹配发生在请求进入 app.__call__() 后,由 url_map.bind() + match() 完成,此时才提取 URL 参数并调用对应函数。
- 函数体内的
request.args、session、g都依赖当前请求上下文,未进入请求循环前访问会抛RuntimeError: Working outside of application context - 动态添加路由(如运行时调用
add_url_rule())可行,但修改后需重启开发服务器才能被 Werkzeug 的重载机制识别 - 使用
methods=["POST"]时,Flask 不会自动拦截 GET 请求——它只决定“匹配成功后是否允许该 method”,405 错误由MethodView.dispatch_request或默认处理逻辑返回
g、session、request 这三个对象的生命周期差异
g 是请求内全局命名空间,生命周期=单次请求;session 默认基于签名 Cookie,跨请求持久但受密钥和过期时间约束;request 是当前请求的解析结果,只读且不可序列化。
立即学习“Python免费学习笔记(深入)”;
-
g在首次访问时懒创建,未赋值的属性访问会返回AttributeError,不能像dict一样用get() -
session修改后必须调用session.modified = True才能强制写回响应 Cookie(尤其在非 JSON 可序列化类型如datetime存入后) -
request.json在 Content-Type 不为application/json或 body 为空时返回None,不是抛异常 —— 别直接链式调用request.json.get("x")而不做判空
from flask import Flask, g, request, sessionapp = Flask(name) app.secret_key = b'your-secret-key'
@app.before_request def before(): g.db_conn = get_db_connection() # 每次请求新建连接 if 'user_id' not in session: session['user_id'] = generate_id()
@app.route('/data') def data(): return {'user': session['user_id'], 'db_ready': hasattr(g, 'db_conn')}
真正难的是上下文管理边界:比如在后台线程里试图读 g 或 session,或者把 request 对象存进缓存——这些操作不会报错,但行为不可预测,因为底层依赖的 _request_ctx_stack 已经退出。










