上下文管理本质(类似于threading.local):

  1.每一个线程都会在Local类中创建一条数据:

{
"唯一标识":{stark:[ctx,]},
"唯一标识":{stark:[ctx,]},
}

  2.当请求进来之后,将请求相关数据添加到列表里面[request,],以后如果使用时,就去读取。

  3.列表中的数据,请求完成之后,将request从列表中移除,

在源码中分析上下文管理:

  1,存数据,2,执行视图函数,3,请求结束。

  第一阶段:执行__call__--->app.wsgi-->将ctx(request,session)封装为RequestContext()在(open_session),app_ctx(g,app)封装为APPContent()通过LocalStack将这两个类放入Local对象中。

# 在封装到RequestContext()时,
# request = Request对象
# session = None # 在执行ctx.push()时,才给session赋予了值。 # ctx.session = self.session_interface.open_session(self,request)

  第二阶段:视图函数导入:request/session/g/app,通过偏函数(_lookup_req_object)在通过(LocalProxy())去LocalStack中的Local类中对其进行增删改查操作。

# 执行视图函数

# response = self.full_dispathch_request()  读取ctx.session将数据写入到浏览器的cookie中。

# 执行偏函数

# request = LocalProxy(partial(_lookup_req_object,"reqeust"))
# _local = 偏函数
# __getattr__
# ctx.request.method ( top, pop ....) # ctx.request.args # session 也在此时写入数据 # session = LocalProxy(partial(_look_req_object,"session")) # _local = 偏函数
# __setitem__
# ctx.session["xx"] == 123

  第三阶段:请求处理完毕:

    通过save_session将签名session保存到cookie.

    通过ctx.pop()去LocalStack中的Local类中将ctx删除。

有关面试问题:

flask和django的区别:
对于django来说,内部组件特别多,自身功能强大,大而全,。
flask内置组件很少,但是第三方组件很多,扩展性强。
因为他们两个框架都没有写socket,都是基于wsgi协议做的,除此之外,flask框架中的上下文管理较为耀眼。
相同点:都没有socket,都是基于wsig协议做的。
不同点:
请求相关的数据传递的方式不同:
django:通过传递request参数取值。
f'lask:
组件不同:
django:大而全。
flask:第三方组件多。

flask上下文管理:

  简单来说,flask上下文管理可以分为三个阶段:

    1,请求进来时,将请求相关的数据放入上下文管理中。

    2,在视图函数中,要去上下文管理中取值。

    3,请求响应,要将上下文管理中的数据清除。

  详细点来说:

    1,请求刚进来,将request,session封装在RequestContext类中,app,g封装在AppContext类中,并通过LocalStack将reqeustcontext和appcontext放入Local类中。

    2,视图函数中,通过LocalProxy-->偏函数-->LocalStack-->Local取值。

    3,请求响应时,先执行save.session()再各自执行pop(),将Local中的数据清除。

Flask中的session是什么时候创建,什么时候销毁:

  当请求进来时,会将request和session封装为一个RequestContext对象。通过LocalStack将RequestContex放入到Local对象中,因为请求第一次进来的时候,session是空值,所以执行open_session,给session赋值,再通过视图函数处理,请求响应时执行save.session,将签名session写入到用户浏览器的cookie中,再将Local中的数值pop掉。

Flask中一共有几个LocalStack和Local对象。

  有两个LocalStack,两个Local。

  request和session共用一个LocalStack和Local。

  g和 app 共用一个LocalStack 和 Local.

为什么把请求放到RequestContext中:

  因为request和session都是在视图中操作频繁的数据,也是用户请求需要用的数据。将request和session封装在RequestContext中,使用top,pop方法,一次就可以完成。如果单独封装,就会操作频繁。

ctx = RequestContext(request,session)

Local的作用:

  保存数据,请求上下文对象和app上下文对象。

LocalStack的作用:

  将Local对象中的数据维护成一个栈 [ctx,ctx,....](先进后出)

  { "协程或线程的唯一标识":{stack: [ ctx,ctx,... ] } }

为什么要维护成一个栈:

  当时web应用时:不过是单线程还是多线程,栈中只有一个数据。

    服务端单线程:{111:{stack:[ ctx, ] }

    服务端多线程:{111:{stack:[ ctx, ] },112:{stack: [ctx, ] }}

    离线脚本:可以在栈中放入多个数据:

      with app01.app_context():

        print(current_app)

        with app02.app_context():

          print(current_app)

        print(current_app)

什么是 g:

  g 相当于一次请求的全局变量,当请求进来时将g和current_app封装为一个APPContext类,再通过LocalStack将AppContext放入到Local类中,取值时t通过偏函数,LocalStack,Local中取值,响应时将Local中的数据g删除。

上下文管理的技术点:

  反射:LocalProxy()

  面向对象,封装:RequestContext

  线程。

Flask上下文管理源码分析的更多相关文章

  1. Flask上下文管理源码分析 ——(3)

    引出的问题 Flask如何使用上下文临时把某些对象变为全局可访问 首先我们做如下的几种情况的假设 情况一:单进程单线程 这种情况可以基于全局变量存储临时的对象 情况二:单进程多线程 这种情况会出现多个 ...

  2. Flask上下文管理源码--亲自解析一下

    前戏 偏函数 def index(a,b): return a+b # 原来的调用方法 # ret=index(1,2) # print(ret) # 偏函数--帮助开发者自动传递参数 import ...

  3. Flask系列之源码分析(一)

    目录: 涉及知识点 Flask框架原理 简单示例 路由系统原理源码分析 请求流程简单源码分析 响应流程简单源码分析 session简单源码分析 涉及知识点 1.装饰器 闭包思想 def wapper( ...

  4. java 1.8 动态代理源码分析

    JDK8动态代理源码分析 动态代理的基本使用就不详细介绍了: 例子: class proxyed implements pro{ @Override public void text() { Syst ...

  5. Spring Boot自动装配原理源码分析

    1.环境准备 使用IDEA Spring Initializr快速创建一个Spring Boot项目 添加一个Controller类 @RestController public class Hell ...

  6. Flask Session 使用和源码分析 —— (6)

    基本使用 from flask import Flask, session, redirect, url_for, escape, request app = Flask(__name__) @app ...

  7. flask/app.py-add_url_rule源码分析

    之前分析route方法的时候,可以看到中间会调用add_url_rule方法,add_url_rule方法和route方法一样属于Flask这个类的. add_url_rule方法主要用来连接url规 ...

  8. JDK7动态代理源码分析

    IObject proxy = (IObject) Proxy.newProxyInstance(IObject.class.getClassLoader(), new Class[]{IObject ...

  9. (转)Spring对注解(Annotation)处理源码分析1——扫描和读取Bean定义

    1.从Spring2.0以后的版本中,Spring也引入了基于注解(Annotation)方式的配置,注解(Annotation)是JDK1.5中引入的一个新特性,用于简化Bean的配置,某些场合可以 ...

随机推荐

  1. HDU 3998

    http://acm.hdu.edu.cn/showproblem.php?pid=3998 求LIS的长度,并且求有多少组互不相交的LIS 求组数用最大流 建图如下: if(dp[i]==1)add ...

  2. VS2015 Release 生成调试信息

    - C/C++ > 常规 > 调试信息格式 - C/C++ > 优化 > 优化 > 禁止(/Od) - 链接器 > 调试 > 生成调试信息 > 是 (/ ...

  3. CF1092(div3):Great Vova Wall (栈)(还不错)

    D1. Great Vova Wall (Version 1): 题意:给定长度为N的墙,以及每个位置的一些高度,现在让你用1*2的砖和2*1的砖去铺,问最后能否铺到高度一样. 思路:分析其奇偶性,在 ...

  4. dockercompose up build fail (node no such file or directory packages.json )

    docker构建项目遇到如下问题: npm ERR! Darwin 15.0.0 npm ERR! argv "/usr/local/lib/node_modules/iojs-bin/no ...

  5. socket套接字和驱动绑定分析

    1. socket()系统调用 socket系统调用是哪个:socket()有3个参数,因此搜索SYSCALL_DEFINE3,然后在检索socket即可. SYSCALL_DEFINE3(socke ...

  6. Digester库使用总结

    1.Digester是Apache软件基金会的Jakarta项目下的子Commons项目下的一个开源项目,Digester API包含3个包:org.apache.commons.digester,提 ...

  7. 【转】linux下解压.bz2压缩文件

    原文网址:http://zhidao.baidu.com/question/90378903.html tar-c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压 ...

  8. mysql 官方docker镜像使用教程

    首先是pull image,这里我拉取的是5.x版本最新版: docker pull mysql:5 拉下来以后大可以按照官方的说明无脑启动,但是外部无法访问,所以绑定端口:docker run -- ...

  9. VS2017增加数据库连接串

    新装VS2017后,按照三石提供的MVC入门教程,创建MVC应用后,能生成数据库文件(在APP_DATA目录),但无法创建连接,服务器路径一直不正确. 解决方法: 1.重新打开VS2017安装界面,选 ...

  10. View绘制基本知识点

    !通过阅读Android开发艺术探索整理   底层工作原理:测量流程.布局流程.绘制流程   常见回调方法:构造方法 onAttach onVisiblityChanged onDetach   Vi ...