flask 的上下文管理

  • Flask的上下文对象

    Flask有两种Context(上下文),分别是

    • RequestContext 请求上下文
    • Request 请求的对象,封装了Http请求(environ)的内容
    • Session 根据请求中的cookie,重新载入该访问者相关的会话信息。
    • AppContext 程序上下文
    • g 处理请求时用作临时存储的对象。每次请求都会重设这个变量
    • current_app 当前激活程序的程序实例

    生命周期:

    • current_app的生命周期最长,只要当前程序实例还在运行,都不会失效。
    • Requestg的生命周期为一次请求期间,当请求处理完成后,生命周期也就完结了
    • Session就是传统意义上的session了。只要它还未失效(用户未关闭浏览器、没有超过设定的失效时间),那么不同的请求会共用同样的session。
    wsgi
  • environ: 一个包含全部HTTP请求信息的字典,由WSGI Server解包HTTP请求生成。
  • start_response: 一个WSGI Server提供的函数,调用可以发送响应的状态码和HTTP报文头, 函数在返回前必须调用一次start_response()
  • application()应当返回一个可以迭代的对象(HTTP正文)。
  • application()函数由WSGI Server直接调用和提供参数。
  • Python内置了一个WSGIREFWSGI Server,不过性能不是很好,一般只用在开发环境。可以选择其他的如Gunicorn

 

flask的上下文管理分为应用(app)上下文管理,和请求(request)上下文管理,

Flask源码流程

 第一部分:请求到来时
 第二部分:视图函数
 第三部分:请求结束前

 

第一部分 : 请求到来时,首先执行app.run() 执行里面的__call__()方法

 def __call__(self, environ, start_response):
        """The WSGI server calls the Flask application object as the
        WSGI application. This calls :meth:`wsgi_app` which can be
        wrapped to applying middleware."""
        return self.wsgi_app(environ, start_response)

然后执行wsgi_app()把environ 和 start_response传进去,执行这句ctx = self.request_context(environ) 返回一个RequestContext对象,environ是请求封装的所有信息,一个字符串对象 RequestContext对象初始化时执行 request = app.request_class(environ) request_class中执行request_class = Request 所有的请求信息都是在Reques类中封装的,得到的ctx对象中有两个属性,ctx.request 和 ctx.session

ctx = self.request_context(environ) --> return RequestContext(self, environ)

    def wsgi_app(self, environ, start_response):
        ctx = self.request_context(environ) #  ctx.request 和 ctx.session
        error = None
        try:
            try:
                ctx.push()
                response = self.full_dispatch_request() # 执行函数 分发
            except Exception as e:
                error = e
                response = self.handle_exception(e)
            except:
                error = sys.exc_info()[1]
                raise
            return response(environ, start_response)
        finally:
            if self.should_ignore_error(error):
                error = None
            ctx.auto_pop(error)

接下来第二部分 执行函数

response = self.full_dispatch_request() 这个函数里判断是否有before_request方法 有就先执行before_request方法,没有继续执行函数

第一步:创建上下文
Flask根据WSGI Server封装的请求等的信息(environ)新建RequestContext对象AppContext对象

# context locals
_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()
current_app = LocalProxy(_find_app)
request = LocalProxy(partial(_lookup_req_object, 'request'))  # 偏函数 得到ctx.request
session = LocalProxy(partial(_lookup_req_object, 'session'))  # 偏函数 得到ctx.session
g = LocalProxy(partial(_lookup_app_object, 'g'))

 

posted @ 2018-08-08 22:18  wzqwer  阅读(134)  评论(0编辑  收藏  举报