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

2024-01-29 11:44

本文主要是介绍(二十一)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, requestapp = 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, requestapp = Flask(__name__)@app.route('/')
def hello_world():print(request)    # LocalProxy对象的__str__     request.method    # LocalProxy对象的__getattr__(key='method')      这一步应该包含多个操作:先去ctx中拿到request,再去request中获取methodreturn '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, sessionapp = Flask(__name__)@app.route('/')
def hello_world():print(request)    # LocalProxy对象的__str__request.method    # LocalProxy对象的__getattr__      这一步应该包含多个操作:先去ctx中拿到request,再去request中获取methodsession['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对象?

  • 都是两个~

这篇关于(二十一)Flask之上下文管理第二篇(细细扣一遍源码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/656795

相关文章

python中的flask_sqlalchemy的使用及示例详解

《python中的flask_sqlalchemy的使用及示例详解》文章主要介绍了在使用SQLAlchemy创建模型实例时,通过元类动态创建实例的方式,并说明了如何在实例化时执行__init__方法,... 目录@orm.reconstructorSQLAlchemy的回滚关联其他模型数据库基本操作将数据添

Elasticsearch 的索引管理与映射配置实战指南

《Elasticsearch的索引管理与映射配置实战指南》在本文中,我们深入探讨了Elasticsearch中索引与映射的基本概念及其重要性,通过详细的操作示例,我们了解了如何创建、更新和删除索引,... 目录一、索引操作(一)创建索引(二)删除索引(三)关闭索引(四)打开索引(五)索引别名二、映射操作(一

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

在Node.js中使用.env文件管理环境变量的全过程

《在Node.js中使用.env文件管理环境变量的全过程》Node.js应用程序通常依赖于环境变量来管理敏感信息或配置设置,.env文件已经成为一种流行的本地管理这些变量的方法,本文将探讨.env文件... 目录引言为什么使php用 .env 文件 ?如何在 Node.js 中使用 .env 文件最佳实践引

python库pydantic数据验证和设置管理库的用途

《python库pydantic数据验证和设置管理库的用途》pydantic是一个用于数据验证和设置管理的Python库,它主要利用Python类型注解来定义数据模型的结构和验证规则,本文给大家介绍p... 目录主要特点和用途:Field数值验证参数总结pydantic 是一个让你能够 confidentl

java 恺撒加密/解密实现原理(附带源码)

《java恺撒加密/解密实现原理(附带源码)》本文介绍Java实现恺撒加密与解密,通过固定位移量对字母进行循环替换,保留大小写及非字母字符,由于其实现简单、易于理解,恺撒加密常被用作学习加密算法的入... 目录Java 恺撒加密/解密实现1. 项目背景与介绍2. 相关知识2.1 恺撒加密算法原理2.2 Ja

Nginx屏蔽服务器名称与版本信息方式(源码级修改)

《Nginx屏蔽服务器名称与版本信息方式(源码级修改)》本文详解如何通过源码修改Nginx1.25.4,移除Server响应头中的服务类型和版本信息,以增强安全性,需重新配置、编译、安装,升级时需重复... 目录一、背景与目的二、适用版本三、操作步骤修改源码文件四、后续操作提示五、注意事项六、总结一、背景与

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的