(二十一)Flask之上下文管理第二篇(细细扣一遍源码)

每篇前言:

  • 🏆🏆作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者

  • 🔥🔥本文已收录于Flask框架从入门到实战专栏:《Flask框架从入门到实战》
  • 🔥🔥热门专栏推荐:《Python全栈系列教程》、《Django框架从入门到实战》、《爬虫从入门到精通系列教程》、《前端系列教程》、《tornado一条龙+一个完整版项目》。
  • 📝​📝本专栏面向广大程序猿,为的是大家都做到Flask从入门到精通,穿插有很多实战优化点。
  • 🎉🎉订阅专栏后可私聊进一千多人Python全栈交流群(手把手教学,问题解答); 进群可领取Python全栈教程视频 + 多得数不过来的计算机书籍:基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。
  • 🚀🚀加入我一起学习进步,一个人可以走的很快,一群人才能走的更远!

在这里插入图片描述

经过上文分析,我们可以将整个过程分为三阶段:

  1. 将ctx对象(包含request和session)放到Local对象中;

  2. 视图函数导入:request/session;

  3. 请求处理完毕:

    • 获取session并加密后保存到cookie
    • 将ctx删掉

第一阶段:

将ctx对象(包含request和session)放到Local对象中。

在这里插入图片描述

进去(下图中self就是ctx对象!):

在这里插入图片描述

继续进:

在这里插入图片描述

显而易见,上述_request_ctx_stack是一个全局变量,在整个应用程序的生命周期中它只创建一次!这是一种单例模式的实现方式~

继续进:

在这里插入图片描述

可以看到这个对象里又包了一个对象,这个_local对象才是真正存ctx的!而上面的_request_ctx_stack对象则相当于是一个代理,每次需要存ctx的时候都要先交给代理,代理再将其给到真正存储ctx的_local对象里!

上述push方法中_local对象点stack又会触发Local对象的__setattr__方法:

在这里插入图片描述

下图以第一阶段为主画了个简单的流程图,以便大家更好地梳理!
在这里插入图片描述

拓展一:flask里的session 是什么时候创建,什么时候销毁的?

当请求刚进来的时候,会将request和session封装成一个request_context对象,接下来通过LocalStack把这个对象放到内部的Local里【注意:现在session还是空的!】

下一步,执行open_session,将cookie里的值拿来处理后再放到Local中的ctx里。

最后,返回的时候要执行save_session将ctx里的session读出来序列化后存到用户cookie中,再将ctx给pop掉~

第二阶段:

分析下图的流程:

在这里插入图片描述

from flask import Flask, request

app = Flask(__name__)


@app.route('/')
def hello_world():
    print(request)    # 执行request对象的__str__方法
    request.method    # 执行request对象的__getattr__(key='method')方法
    return 'hello world~'


if __name__ == '__main__':
    app.__call__
    app.run()

看源码,进request:

在这里插入图片描述

回去:

from flask import Flask, request

app = Flask(__name__)


@app.route('/')
def hello_world():
    print(request)    # LocalProxy对象的__str__     
    request.method    # LocalProxy对象的__getattr__(key='method')      这一步应该包含多个操作:先去ctx中拿到request,再去request中获取method
    return 'hello world~'


if __name__ == '__main__':
    app.__call__
    app.run()

进LocalProxy源码:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

进去_get_current_object()

在这里插入图片描述

__local就是最开始传给LocalProxy的经过偏函数处理的那个函数,下图中的这个:

在这里插入图片描述

__local函数加括号执行这个函数,进去看:

在这里插入图片描述

继续看session:

在这里插入图片描述

如上图所指会执行session对象的__setitem__方法~

进session源码:

和request区别就是传的参数是session:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

跳出来:

在这里插入图片描述

from flask import Flask, request, session

app = Flask(__name__)


@app.route('/')
def hello_world():
    print(request)    # LocalProxy对象的__str__
    request.method    # LocalProxy对象的__getattr__      这一步应该包含多个操作:先去ctx中拿到request,再去request中获取method

    session['k1'] = 'guhanzhe'  # LocalProxy对象的__setitem__(key=k1, value='guhanzhe')      # 先去ctx中拿到session,再给session中设置对应的值
    session['k1']               # LocalProxy对象的__getitem__(key='1')                       # 先去ctx中拿到session,再去session中获取对应的值

    return 'hello world~'


if __name__ == '__main__':
    app.__call__
    app.run()

视图函数中有关于request和session的操作都是通过LocalProxy对象这个中介操作,然后再通过函数_lookup_req_object去ctx获取到request和session对象。

在这里插入图片描述

第三阶段:

pop肯定也不是直接pop的,也要走中介,如下图蓝色流程线:

在这里插入图片描述

但是上述所画几个流程图其实都不全,所以再来缕一遍源码:

进push:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这个AppContext对象中,又封装了两个值:app和g!

在这里插入图片描述

回退:

在这里插入图片描述

封装了那两个值后执行app_ctx.push(),再来看看app_ctx是啥?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

所以流程图又要更新了!这次多了个存放app(就是程序进来实例化的Flask对象)和g的对象!!!

完整画图:

在这里插入图片描述

上面刚说多了个g和app:
在这里插入图片描述

进去g:

在这里插入图片描述
在这里插入图片描述

进去current_app:
在这里插入图片描述

是不是和request和session一个流程!!!

最后来看看最后的最后:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

把最后的最后补充进图:

在这里插入图片描述

上面这个机制支持多线程!

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

  • 都是两个~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/355791.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MISRA C 2012】Rule 5.6 类型定义名称应该是唯一的标识符

1. 规则1.1 原文1.2 分类 2. 关键描述3. Example4. 代码实例 1. 规则 1.1 原文 1.2 分类 规则5.6:类型定义名称应该是唯一的标识符 Required要求类规范。 2. 关键描述 typedef名称在所有名称空间和翻译单元中应该是唯一的。只有当类型定义在头文件中并且该头文件…

HiveSQL题——窗口函数(lag/lead)

目录 一、窗口函数的知识点 1.1 窗户函数的定义 1.2 窗户函数的语法 1.3 前后函数:lag/lead 二、实际案例 2.1 股票的波峰波谷 0 问题描述 1 数据准备 2 数据分析 3 小结 2.2 前后列转换(面试题) 0 问题描述 1 数据准备 2 数据分析 3 小结…

【C语言】linux内核ipoib模块 - ipoib_netdev_ops_pf结构

一、ipoib_netdev_ops_pf结构 static const struct net_device_ops ipoib_netdev_ops_pf {.ndo_init ipoib_ndo_init,.ndo_uninit ipoib_ndo_uninit,.ndo_open ipoib_open,.ndo_stop ipoib_stop,.ndo_change_mtu ipoib_change_mtu,.ndo_…

将word中插入的zotero文献转为latex引用样式

在word中,可以使用zotero插件插入和管理参考文献。 例如: 若需要将这段内容移植到latex,就需要将对应的引用编号用\cite{}替换。手动替换非常麻烦且容易出错。要实现自动转换,可在zotero中定制一种新的引文格式,自动将…

【大数据】Flink 架构(六):保存点 Savepoint

《Flink 架构》系列(已完结),共包含以下 6 篇文章: Flink 架构(一):系统架构Flink 架构(二):数据传输Flink 架构(三):事件…

云上高可用系统-韧性设计模式

一、走近韧性设计模式 (一)基本概念 韧性设计模式是一系列在软件工程中用于提高系统韧性的设计原则、策略、实践和模式。韧性(Resilience)在这里指的是系统对于各种故障、异常和压力的抵抗能力,以及在遭受这些挑战后…

重生奇迹MU弓箭手技能搭配

重生奇迹mu弓箭手技能怎么选择和搭配呢?重生奇迹mu弓箭手是一个远程射手定位的英雄,下面为大家带来重生奇迹mu弓箭手技能选择攻略。 首先,从人物属性上看,弓箭手属于敏捷型高攻单位。在重生奇迹mu中敏捷属性带来的收益在于高质量…

Mac下查看、配置和使用环境变量

Mac下查看、配置和使用环境变量 一:Mac怎么查看环境变量命令 printenv一:这个命令会一次性列出所有环境变量的键值对,输出格式为: VAR1value1 VAR2value2 ...二: 也可以通过给这个命令加上环境变量名参数&#xff0…

循环购模式——解决用户复购难 用户粘性差!

随着电商市场的竞争加剧,消费者需求日益多样化,电商企业需要不断创新以满足市场需求。循环购模式作为一种新兴的消费模式,正逐渐受到消费者的青睐,成为电商行业的新热点。本文将深入剖析循环购模式的魅力,探索其在电商…

天猫超市卡回收平台

京回收等卡商能回收天猫超市卡 天猫商城当中的天猫超市,实际也是类似于京东自营店有关销售货物模式,对于天猫超市里面的东西,均是由天猫进行管理,并从商品的采购,就是一手进行操作。相关的物品,以相关商城会…

JVM篇----第十四篇

系列文章目录 文章目录 系列文章目录前言一、JVM 类加载机制二、类加载器三、双亲委派前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 一、JVM 类加载机制 JVM 类…

【每日一题】5.LeetCode——环形链表

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有限,欢迎各位大佬指点&…

JS基础 - 遍历对象方法(6种)

初始值: var obj {a: 1,b: 2,c: 3,d: 4,e: 5,}; 第一种:for in for (let key in obj) {console.log(key ":" obj[key]);} 第二种:Object.keys 获取key Object.keys(obj).forEach((key) > {console.log(key ":" …

RT-DETR改进有效系列目录 | 包含卷积、主干、RepC3、注意力机制、Neck上百种创新机制

💡 RT-DETR改进有效系列目录 💡 前言 Hello,各位读者们好 Hello,各位读者,距离第一天发RT-DETR的博客已经过去了接近两个月,这段时间里我深入的研究了一下RT-DETR在ultralytics仓库的使用,旨在为大家解决为什么用v8的仓库训练的时候模型不收敛,精度差的离谱的问题,…

swift - reduce简介

reduce 减少&#xff0c;降低&#xff1b;&#xff08;烹调中&#xff09;使变浓稠&#xff0c;收汁&#xff1b;<美>节食减肥&#xff1b;使沦为&#xff0c;使陷入&#xff08;不好的境地&#xff09;&#xff1b;迫使&#xff0c;使不得不&#xff08;做&#xff09;&…

自然语言处理中的词云生成

一.词云的介绍 自然语言处理中的词云技术是文本可视化的一种形式&#xff0c;用于展示文本数据中词语的频率分布。以下是词云在自然语言处理中的基本介绍和发展&#xff1a; 起源和发展&#xff1a; 词云的概念最初来源于信息可视化领域&#xff0c;用于将文本中的关键词以视…

脉宽调制器

1. pwm脉宽调制器 脉宽调制器: 一种硬件设备, 用于 动态调制 方波 的 一些属性, 方波的周期,频率,占空比 占空比? : 有效电平占 整个周期的比值 可以使用PWM 控制功率, 控制频率 用于 开关电源 或 逆变器 1.1 原理 PWM原理: 如图所示 本质就是一个定时器: 由原理…

游戏开发丨基于Pygame的AI版贪吃蛇小游戏

文章目录 写在前面需求分析程序设计程序分析运行结果系列文章写在后面 写在前面 本期内容 基于pygame的AI版贪吃蛇小游戏 所需环境 pythonpycharm或anacondapygame 下载地址 https://download.csdn.net/download/m0_68111267/88789665 需求分析 本游戏使用Pygame模块开…

FL Studio21.2.2中文学生版免费下载(支持简体中文,支持苹果M1/M2处理器)

今天小编给大家带来的是一款功能非常强大的音乐创作编辑软件它就是(水果软件)。使用FL Studio21中文版可以轻松帮我们制作自己的音乐唱片&#xff0c;拥有强大且专业的创作工具&#xff0c;COCO玛奇朵为您提供FL Studio(水果软件)2024免费下载&#xff0c; FL Studio 21 Win-安…

ASCP电气防火限流式保护器功能以及应用场景

功能&#xff1a; ASCP200型电气防火限流式保护器可有效克服传统断路器、空气开关和监控设备存在的短路电流大、切断短路电流时间长、短路时产生的电弧火花大&#xff0c;以及使用寿命短等弊端&#xff0c;发生短路故障时&#xff0c;能以微秒级速度快速限制短路电流以实现灭弧…