本文主要梳理了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