阅读flask源码2:Local,LocalStack

2024-03-16 22:08

本文主要是介绍阅读flask源码2:Local,LocalStack,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我们还是以flask0.1的代码来阅读,先提出几个常见的问题:

1上下文是怎么被压入栈的?

2为什么在不同的程序中通过相同的变量request可以拿到对应的请求

我们先看第一个问题:上下文是怎么被压入栈的?

服务器传过来的请求参数,被封装成了一个_RequestContext对象,这个对象里有这个请求相关联的一组互相“绑架”的参数,它们组成一个上下文环境。比如request,被实例化的app。如下:

class _RequestContext(object):def __init__(self, app, environ):self.app = appself.url_adapter = app.url_map.bind_to_environ(environ)self.request = app.request_class(environ)self.session = app.open_session(self.request)self.g = _RequestGlobals()self.flashes = Nonedef __enter__(self):_request_ctx_stack.push(self)def __exit__(self, exc_type, exc_value, tb):# do not pop the request stack if we are in debug mode and an# exception happened.  This will allow the debugger to still# access the request object in the interactive shell.if tb is None or not self.app.debug:_request_ctx_stack.pop()

这个对象实现了__enter__,所以通过with context语句。对象被压入到一个栈中。

 def push(self, obj):"""Pushes a new item to the stack"""rv = getattr(self._local, "stack", None) # 如果没有stack,那么就返回none,然后给_local创建一个stack属性。if rv is None:self._local.stack = rv = [] # 新建一个列表,把这个列表给自己的属性_local,它是一个对象。rv.append(obj) # 给自己的属性_local的属性,加上一个上下文环境对象,这个对象在请求进来时已经通过with实例化了一个。return rv

字典的键是线程Id,值就是被压入的,封装了特定请求的上下文对象。那么问题来了,正常情况下,context被压入栈中,栈里应该是context对象啊。是怎么实现里面有字典的呢?

压入栈中,这个压入,可不是压入一个普通的列表,这个列表,将做为Local对象的一个属性stack

这个LocalStack初始化的时候,封装了一个Local对象。为什么要这样做呢?这就回答了上面的问题,Local可以实现线程隔离,拿到当前线程的上下文。

这里Local实现了一个__setattr__方法,这样可以加上线程了,现在上下文按放在一个Local对象的字典中,

上面是存储好了上下文环境 ,下面是讲解,怎么通过全局变量拿到request的呢?

我们进入视图函数了,我们输入:request.url。

@app.route('/')
def index():req = request.urlreturn req

这个时候,request是一个代理对象,

request = LocalProxy(lambda: _request_ctx_stack.top.request)

_request_ctx_stack.top.request)会从栈中取出最上面的对象,并且拿到栈最上面的上下文对象。

它本身没有url属性,所以会触发LocalProxy的__getattr__属性。这个时候,拿到request对象的url属性。

这篇关于阅读flask源码2:Local,LocalStack的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

python web 开发之Flask中间件与请求处理钩子的最佳实践

《pythonweb开发之Flask中间件与请求处理钩子的最佳实践》Flask作为轻量级Web框架,提供了灵活的请求处理机制,中间件和请求钩子允许开发者在请求处理的不同阶段插入自定义逻辑,实现诸如... 目录Flask中间件与请求处理钩子完全指南1. 引言2. 请求处理生命周期概述3. 请求钩子详解3.1

Python Flask 库及应用场景

《PythonFlask库及应用场景》Flask是Python生态中​轻量级且高度灵活的Web开发框架,基于WerkzeugWSGI工具库和Jinja2模板引擎构建,下面给大家介绍PythonFl... 目录一、Flask 库简介二、核心组件与架构三、常用函数与核心操作 ​1. 基础应用搭建​2. 路由与参

8种快速易用的Python Matplotlib数据可视化方法汇总(附源码)

《8种快速易用的PythonMatplotlib数据可视化方法汇总(附源码)》你是否曾经面对一堆复杂的数据,却不知道如何让它们变得直观易懂?别慌,Python的Matplotlib库是你数据可视化的... 目录引言1. 折线图(Line Plot)——趋势分析2. 柱状图(Bar Chart)——对比分析3

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整

Python中Flask模板的使用与高级技巧详解

《Python中Flask模板的使用与高级技巧详解》在Web开发中,直接将HTML代码写在Python文件中会导致诸多问题,Flask内置了Jinja2模板引擎,完美解决了这些问题,下面我们就来看看F... 目录一、模板渲染基础1.1 为什么需要模板引擎1.2 第一个模板渲染示例1.3 模板渲染原理二、模板

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

Python 安装和配置flask, flask_cors的图文教程

《Python安装和配置flask,flask_cors的图文教程》:本文主要介绍Python安装和配置flask,flask_cors的图文教程,本文通过图文并茂的形式给大家介绍的非常详细,... 目录一.python安装:二,配置环境变量,三:检查Python安装和环境变量,四:安装flask和flas

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很