flask 上下文的实现
admin
2023-07-31 01:44:33
0

引言

本文主要梳理了flask的current_app, request, session, g的实现原理

源码说明

本文使用flask 0.5 版本

application context 和request context

flask有两个context: application contextrequest context

application context request context
current_app request
g session

这里需要通俗地解释一下application contextrequest context

  1. application 指的就是当你调用app = Flask(__name__)创建的这个对象app

  2. request 指的是每次http请求发生时,WSGI server(比如gunicorn)调用Flask.__call__()之后,在Flask对象内部创建的Request对象;

  3. application 表示用于响应WSGI请求的应用本身,request 表示每次http请求;

  4. application的生命周期大于request,一个application存活期间,可能发生多次http请求,所以,也就会有多个request

下面通过源码了解一下 flask 如何实现这两种context:

# 代码摘选自flask 0.5 中的ctx.py文件, 进行了部分删减
class _RequestContext(object):
    
    def __init__(self, app, environ):
        self.app = app
        self.request = app.request_class(environ)
        self.session = app.open_session(self.request)
        self.g = _RequestGlobals()

flask 使用_RequestContext的代码如下:

class Flask(object):

    def request_context(self, environ):
        return _RequestContext(self, environ)

Flask类中,每次请求都会调用这个request_context函数。这个函数则会创建一个_RequestContext对象。

值得注意的是:这个对象在创建时,将Flask实例的本身作为实参传入_RequestContext自身,因此,
self.app = Flask()

所以,虽然每次http请求都会创建一个_RequestContext对象,但是,每次创建的时候都会将同一个Flask对象传入该对象的app成员变量,使得:

由同一个Flask对象响应的请求所创建的_RequestContext对象的app成员变量都共享同一个application

通过在Flask对象中创建_RequestContext对象,并将Flask自身作为参数传入_RequestContext对象的方式,实现了多个request context对应一个application context 的目的。

接下来,看self.request = app.request_class(environ)这句。
由于app成员变量就是app = Flask(__name__)这个对象,所以,app.request_class就是Flask.request_class
Flask类的定义中:

request_class = Request # Request 是一个类,定义如下:

class Request(RequestBase):
    ...

所以:
self.request = app.request_class(environ)实际上是创建了一个Request对象。
由于,一个http请求对应一个_RequestContext对象的创建,而每个_RequestContext对象的创建对应一个Request对象的创建,所以,每个http请求对应一个Request对象。

到这里想必已经很清楚了:

application 就是指app = Flask(__name__)对象
request 就是对应每次http 请求创建的Request对象
flask通过_RequestContextappRequest关联起来

总结

  1. app = Flask(__name__)创建了application, 这个application对应的上下文,就是application context

  2. Flask每响应一个http请求,就会创建一个Request对象,这个request对象对应的上下文,就是request context

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...