在 Flask 中有个 context 即上下文的概念。一直不是很理解,今天查阅了多方资料,有了一个基础的认识。简单的总结一下
上下文概念
上下文的原文是 context,简单的理解上下文的含义是指:在处理一个请求的时候所要包含的前提条件(及后续条件)。比如我们需要在每次请求之前要知道的数据库连接信息,所在的应用信息,用户的请求信息等。
Flask中的上下文对象
RequestContent 请求上下文
- Request 请求的对象,会封装每次的 Http 请求 (environ) 的内容;
- Session 会根据请求中的 cookie,重新载入该访问者相关的会话信息。
AppContext 应用上下文
- g 处理请求时用作临时存储的对象,每次请求都会重设这个变量;作为一个请求内的全局变量,可以在用于在装饰器 before_request() 、 after_request() 和 teardown_request() 中保存变量信息。 在0.10之后它可以作用于整个应用。
- current_app 当前激活的应用,在多应用时候可以准确的定位到目前所用的app。
生命周期
- current_app 的生命周期最长,只要当前实例还在运行中,它就不会失效。
- g 和 Request 的生命周期都是一个请求的周期。一个请求结束后,其生命周期也结束了。
- session的生命周期取决于它是否过期用户是否关闭浏览器等,跟普通的 session 生命周期一样。
创建模式
Flask 启动时会有两种状态,开始的状态可以做些应用级的初始化;当第一个请求过来之后,就进入了另外的一个状态,具体请参考官方文档。
应用上下文
在应用上下文中,包括了 current_app、g 两个对象,一般来说,该对象有如下的两种创建方式:
- 在处理请求的时候会自动创建;
- 通过 app_context() 手动创建,通常用在一些单元测试的场景中。
- 官方文档中文介绍
请求上下文
在请求上下文中,包含了 request 、 session 两个对象,同样有如下两种创建方式:
- 在处理请求的时候自动创建
- 通过app.test_request_context(‘/route?param=value’)手动创建。
需要注意的是,如果创建请求上下文时候,当前没有应用上下文,则会自动创建应用上下文。也就是说请求上下文一定是在应用上下文存在的基础上存在的。 - 官方文档中文介绍
线程安全
在处理 request 请求的时候,在线程或协程环境下,各线程是如何有条不紊的调用自己的变量的。
flask 中的线程安全
在 Python 中的线程安全机制是 treadin.local(), 而 flask 中的线程安全机制是使用werkzeug中的Local 实现的。除了线程,它还支持协程。
flask 中定义
在 flask 中,上下文的定义存在于 globals.py 中。
LocalProxy 和 LocalStack
LocalProxy 和 LocalStack 都是werkzeug中定义的。
LocalProxy 是一个代理对象,它能够把接收到的请求转发给本地的local 对象,而LocalStack 则是一个模拟了堆栈实现保存与线程相关的变量,使不同线程的变量不会混淆。
上下文源码
上下文相关的源码在 ctx.py 中。