开发环境下Flask启动流程
命令解析 -> 初始化应用实例(加载配置/组件) -> 启动WSGI服务器 -> 监听端口等待请求
阶段1. 终端命令启动时,启动命令解析
- Click库 解析终端参数(如–host=0.0.0.0、–port=8080、–debug);
- 读取系统环境变量(FLASK_APP/FLASK_ENV/FLASK_DEBUG等),定位应用的启动文件(如app.py)和应用实例名(如app,格式FLASK_APP=文件名:实例名);
- 校验DEBUG模式:如果开启,会启用热重载、调试器等开发特性
阶段2. 应用实例初始化(启动前的准备)
创建 Flask 应用对象(app = Flask(name))
- 加载基础配置:默认配置(如DEBUG=False、SECRET_KEY=None)+ 自定义配置(如app.config[‘DEBUG’] = True)
- 初始化核心组件
- 路由映射表(url_map):空的字典结构,用于存储@app.route()装饰的 URL 和视图函数的对应关系
- 模板环境(Jinja2):初始化模板加载路径、过滤器、上下文处理器
- 上下文栈(请求上下文 / 应用上下文):Werkzeug 提供的栈结构,用于管理请求生命周期
- 扩展注册:初始化已绑定的扩展(如 Flask-SQLAlchemy)
阶段3. WSGI服务器初始化
Flask本身不实现服务器,开发环境下,核心依赖Werkzeug的WSGI服务器:
- 把Flask应用实例(符合WSGI规范的可调用对象)传递给Werkzeug的BaseWSGIServer;
- 绑定指定的host(默认 127.0.0.1)和port(默认 5000),创建 TCP 套接字(Socket);
- 初始化请求处理器:Werkzeug 创建WSGIRequestHandler,用于后续解析 HTTP 请求、调用 Flask 应用处理请求。
阶段4. 启动监听循环
- 服务器启动并进入无限监听循环:监听绑定的端口,等待客户端的TCP连接
- 初始化信号机制:通过Blinker触发app_starting信号,执行注册的回调函数
- 调试模式额外操作:如开启DEBUG=True,启动文件监控器,监测代码文件变化后自动重启服务器
阶段5. 服务就绪
- 终端输出启动日志(如* Running on http://127.0.0.1:5000)
- 此时服务器已准备就绪,可接受并处理请求(每次请求会触发Flask的请求处理流程,如路由匹配、视图函数执行、响应返回)
Flask 是典型的微框架,仅保留了核心功能:请求响应处理和模板渲染。
创建程序对象
from flask import Flask
app = Flask(__name__) # 传入存储当前模块名称的特殊变量 __name__
模版渲染
模板(template):包含变量和运算逻辑的 HTML 或其他格式的文本。
渲染(rendering):模版中执行变量替换和逻辑计算工作的过程。
模板渲染引擎——Jinja2
常用定界符: 、、、
- { {} } 用来标记变量
- { % … % } 用来标记语句,比如 if 语句,for 语句等
- {# … #} 用来写注释 、、、
templates/index.html:主页模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>'s Watchlist</title>
</head>
<body>
<h2>'s Watchlist</h2>
{# 使用 length 过滤器获取 movies 变量的长度 #}
<p> Titles</p>
<ul>
{# 使用 endfor 标签结束 for 语句 #}
</ul>
<footer>
<small>© 2025 <a href="http://helloflask.com/book/3">HelloFlask</a></small>
</footer>
</body>
</html>
请求响应处理
注册视图函数,即使用 app.route() 装饰器来为这个函数绑定对应的 URL。
from flask import Flask, render_template
app = Flask(__name__)
name = 'Grey Li'
movies = [
{'title': 'My Neighbor Totoro', 'year': '1988'},
{'title': 'Dead Poets Society', 'year': '1989'},
{'title': 'A Perfect World', 'year': '1993'},
]
@app.route('/')
def index():
return render_template('index.html', name=name, movies=movies)
render_template() 函数在调用时会识别并执行 index.html 里所有的 Jinja2 语句,返回渲染好的模板内容。在返回的页面中,变量会被替换为实际的值(包括定界符),语句(及定界符)则会在执行后被移除(注释也会一并移除)