flask 上下文的實現

發表於2016-03-31

引言

本文主要梳理了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 使用_RequestContext的程式碼如下:

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類的定義中:

所以:
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

相關文章