本文主要梳理了flask的current_app, request, session, g的实现原理python
本文使用flask 0.5 版本flask
flask有两个context: application context
和request context
session
application context | request context | |
---|---|---|
current_app | request | |
g | session |
这里须要通俗地解释一下application context与request context:app
application 指的就是当你调用app = Flask(__name__)
建立的这个对象app
;函数
request 指的是每次http
请求发生时,WSGI server
(好比gunicorn)调用Flask.__call__()
以后,在Flask
对象内部建立的Request
对象;spa
application 表示用于响应WSGI请求的应用自己,request 表示每次http请求;code
application的生命周期大于request,一个application存活期间,可能发生屡次http请求,因此,也就会有多个requestserver
下面经过源码了解一下 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经过_RequestContext
将app
与Request
关联起来
app = Flask(__name__)
建立了application, 这个application对应的上下文,就是application context
Flask
每响应一个http请求,就会建立一个Request
对象,这个request对象对应的上下文,就是request context