引言

本文主要梳理了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

(搬运以学习)flask 上下文的实现的更多相关文章

  1. 用尽洪荒之力学习Flask源码

    WSGIapp.run()werkzeug@app.route('/')ContextLocalLocalStackLocalProxyContext CreateStack pushStack po ...

  2. flask上下文详解

    一.前言 了解过flask的python开发者想必都知道flask中核心机制莫过于上下文管理,当然学习flask如果不了解其中的处理流程,可能在很多问题上不能得到解决,当然我在写本篇文章之前也看到了很 ...

  3. Flask上下文管理、session原理和全局g对象

    一.一些python的知识 1.偏函数 def add(x, y, z): print(x + y + z) # 原本的写法:x,y,z可以传任意数字 add(1,2,3) # 如果我要实现一个功能, ...

  4. 学习Flask框架

      # -*- encoding: utf-8 -*- #导包 from flask import Flask #建立flask对象 app = Flask(__name__) #使用flask路由器 ...

  5. 初步了解学习flask轻量级框架,

    关于flask我有话说 flask作为一个轻量级框架,它里面有好多扩展包需要下载,比较麻烦,而且有的时候flask需要在虚拟环境下运行,但是他的优点还是有滴 ,只要是用过Django的人,都会觉得fl ...

  6. flask上下文全局变量,程序上下文、请求上下文、上下文钩子

    Flask上下文 Flask中有两种上下文,程序上下文(application context)和请求上下文(request context) 当客户端发来请求时,请求上下文就登场了.请求上下文里包含 ...

  7. Flask上下文管理

    一.一些python的知识 1.偏函数 def add(x, y, z): print(x + y + z) # 原本的写法:x,y,z可以传任意数字 add(1,2,3) # 如果我要实现一个功能, ...

  8. Flask 上下文(Context)原理解析

    :first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { border: 0; m ...

  9. 学习flask的网址

    学习flask的网址: http://www.bjhee.com

随机推荐

  1. 自定义ExtJS文件上传

    日常工作中,一般文件上传都是跟随表单一起提交的,但是遇到form表单中有许多地方有文件上传时这种方式却不是很适用,以下是我工作中用的文件上传方式: { xtype: 'fileuploadfield' ...

  2. mysql五补充:SQL逻辑查询语句执行顺序(待完善)

    一.SELECT语句关键字的定义顺序(语法顺序) SELECT DISTINCT <select_list> FROM <left_table> <join_type&g ...

  3. html+css动态篇

    transition过渡 transform旋转 animation动画 一般是父div包含两个子div,一个写鼠标悬浮之前,一个写鼠标悬浮之后, 鼠标悬浮之后的div要写overflow:hidde ...

  4. JS监测鼠标指针位置

    需求1:鼠标移入正方形的时候,蓝色小圆点跟随鼠标滚动(不许蓝色小圆点超出正方形区域),正方形里实时显示当前鼠标相对于body的坐标. <!DOCTYPE html> <html la ...

  5. PHP基础--strtr和str_replace字符替换函数

    (一)strtr是字符替换函数 (1)单个字符替换: <?php echo strtr("abba", "ab", "10"),&qu ...

  6. Angular 5.x 学习笔记(2) - 生命周期钩子 - 暂时搁浅

    Angular 5.x Lifecycle Hooks Learn Note Angular 5.x 生命周期钩子学习笔记 标签(空格分隔): Angular Note on cnblogs.com ...

  7. JAVA利用jxl读取Excel内容

    JAVA可以利用jxl简单快速的读取文件的内容,但是由于版本限制,只能读取97-03  xls格式的Excel. import java.io.File; import java.io.FileInp ...

  8. gridview导出exe处理时遇到RegisterForEventValidation can only be called during Render();错误

    如题,今天在利用GridView作execl导出时,遇到RegisterForEventValidation can only be called during Render();问题.根据网上找到的 ...

  9. 二、Python安装扩展库

    第一步:推荐easy_install工具 下载地址:https://pypi.python.org/pypi/setuptools 下载"ez_setup.py"文件; 通过运行c ...

  10. March 2 2017 Week 9 Thursday

    The first duty of love is to listen. 爱的首要责任是倾听. Yesterday, I read an article that says a successful ...