• (搬运以学习)flask 上下文的实现


    引言

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

    源码说明

    本文使用flask 0.5 版本

    application context 和request context

    flask有两个context: application contextrequest 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通过_RequestContextappRequest关联起来

    总结

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

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

  • 相关阅读:
    Python M3 面向对象
    Python 基础
    Python 基础
    Python 基础
    Python 作业
    Python 基础
    Python 基础
    【机器学习】周志华 读书笔记 第三章 线性模型
    【机器学习】周志华 读书笔记 第二章 模型评估与选择
    【机器学习】周志华 读书笔记 第一章 绪论
  • 原文地址:https://www.cnblogs.com/wf-skylark/p/9218879.html
Copyright © 2020-2023  润新知