Flask 上下文


在 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 中。


参考文章: 本文章更详细的叙述了有关上下文的源码及实现原理