分享

flask 上下文的实现

 River_LaLaLa 2016-08-21


来源:_Zhao 

链接:https://segmentfault.com/a/1190000004223296


引言


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


源码说明


本文使用flask 0.5 版本


application context 和request context


flask有两个context: application context和request context




这里需要通俗地解释一下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通过_RequestContext将app与Request关联起来


总结


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

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


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多