flask 上下文的實現

引言

本文主要梳理了flask的current_app, request, session, g的實現原理python

源碼說明

本文使用flask 0.5 版本flask

application context 和request context

flask有兩個context: application contextrequest contextsession

application context request context
current_app request
g session

這裏須要通俗地解釋一下application contextrequest contextapp

  1. application 指的就是當你調用app = Flask(__name__)建立的這個對象app函數

  2. request 指的是每次http請求發生時,WSGI server(好比gunicorn)調用Flask.__call__()以後,在Flask對象內部建立的Request對象;spa

  3. application 表示用於響應WSGI請求的應用自己,request 表示每次http請求;code

  4. 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經過_RequestContextappRequest關聯起來

總結

  1. app = Flask(__name__)建立了application, 這個application對應的上下文,就是application context

  2. Flask每響應一個http請求,就會建立一個Request對象,這個request對象對應的上下文,就是request context

相關文章
相關標籤/搜索