千家信息网

Flask的上下文管理详解

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容介绍了"Flask的上下文管理详解"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Flask线
千家信息网最后更新 2026年11月02日Flask的上下文管理详解

本篇内容介绍了"Flask的上下文管理详解"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

Flask线程间上下文安全

Falsk完成线程安全的原理,是在启动之后进程里维护request栈和app栈,栈是通过线程ID来保证每个请求的线程安全。

实现主要依赖三个类Local,LocalStack和LocalProxy,下面看一下具体的实现原理

三个类构建本地数据

1. Local

先看Local的源码,实质并不是Flask中定义的,而是Flask依赖的werkzeug库所定义。

可以看到其定义的两个属性__storage__, __ident_func__以及三个方法__getattr__,__setattr__,__release_local__。

1.属性__storage__是多层级字典,第一层key是隐含的线程ID或者协程ID,第二层的key是实际使用的关键字

2.属性__ident_func__可以看到是get_ident函数,get_ident函数要么是通过thread库获取当前执行单元的线程ID,要么是通过greenlet库获取当前执行协程的协程ID。

另外可以看到Local这个类的三个方法,实质是通过重写Python内置函数__setattr__和__getattr__来实现线程或者协程间数据隔离

1.获取local某属性时如:local.age实质触发的是__getattr__方法先获取到当前线程ID--__ident_func__函数获取,然后在__storage__字典中找到线程ident对应的结果集从获取到的结果中再查找age属性

2.设置local某属性时如:local.age = 12 实际触发的是__setattr__方法先获取到当前线程ID--__ident_func__函数获取,然后在__storage__字典设置相应的属性字典集

另一个__release_local__方法就是将相应的线程数据删除。

画个简图比较起来更直观一些。

主线程中生成一个对象local=Local(),三个线程中进行相同的操作local.no=每个线程对应的数。为每个线程都开辟一个存储,所以谁来取或者存就找到自己对应中的位置,虽然取得key都一样,但是每次存取都是只关于自己的值。

2. LocalStack

LocalStack也是定义在Flask所依赖的werkzeug库,从字面意思来理解,它就是Local的堆栈操作,看一下源码如何定义。

LocalStack实质就是围绕着Local来进行操作,根据上面我们读完Local的源码可以看到,

  1. LocalStack定义了一个Local对象

  2. 给这个对象设置了一个stack属性,且这个属性是一个列表

  3. LocalStack中定义了对这个列表进行压栈,出栈等方法

  4. 给类中的Local对象提供了自定义ident_func的方法

3. LocalProxy

LocalProxy字面意思就是做一个Local的代理,我们先从一个request的定义来看LocalProxy的用法,然后结合源码来看LocalProxy到底是用来做什么?

类中稍微有些难理解的就是关于object.__setattr__(self, "_LocalProxy__local", local)的作用,实际就是给self设置一个__local属性。这是Python类中关于私有变量的定义。可以看Python的官方定义python私有变量。

可以看到这个类将所有Python类所内置的方法都进行重写,重写后所有的操作都是基于类中所定义的_get_current_object方法返回的对象进行操作。

而这个方法中返回值就是初始化时所给定的local对象执行返回的结果。如果创建时指定的不是Local对象,则直接执行此方法。如果给定的是Local对象,则根据类名查找对应的对象。

现在这个比较抽象,这个代理到底是做的什么? 我们结合Flask定义全局的request对象来看。假如我们想获取请求的方法是什么,那我们使用的就是request.method。

下面是request定义的源码

  1. 根据LocalProxy的源码中重写的__getattr__方法,先执行_get_current_object方法获取到对象,然后再获取返回对象method属性。

  2. 创建LocalProxy时传递的函数是_lookup_req_object的偏函数,实际就是_lookup_req_object且name=request

  3. 再LocalProxy中__local就是一个函数,所以在执行_get_current_object就是执行_lookup_req_object且name=request返回的值,然后再取其method属性

  4. 此时再执行_lookup_req_object函数,从_request_ctx_stack获取top的request

使用Proxy可以简单快捷的使用request.method获取相应的值,其核心就是每次获取时都会执行对应的函数,而函数中每次返回的值都是线程安全。保证数据正确且优雅。 否则我们每次都去执行一个函数来获取其值,然后再取其属性。

"Flask的上下文管理详解"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

线程 属性 方法 函数 对象 就是 源码 三个 实际 安全 字典 实质 数据 上下 上下文 结果 管理 内容 原理 变量 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 花魁咖啡 互联网科技海报 南京欣网互联网络科技有限公司 互联网科技有限公司经营范围 互联网金融 科技金融 安徽鑫晟辉互联网科技 成都狮子座互联网科技 互联网科技有限公司 翻译 互联网科技大会案例 开启互联网科技时代小说 宁夏众和广鑫互联网科技有限公司 迪庆互联网科技招生 翼展科技 首家互联网医院 上海京穆互联网科技有限公司 互联网企业科技类企业如何做账 互联网与数字科技关系 容联科技互联网电商 互联网科技博主张洲 科技互联网专业务虚会材料 黑龙江互联网科技公司 科技互联网技术 互联网科技素材视频竖屏 联恩商钥互联网科技有限公司 广州新华互联网科技学校电竞方面 科技互联网的核心竞争力 2021互联网科技公司排名 广州梦谷互联网科技有限公司领导 北京军民互联网科技公司 玉溪新华互联网科技怎么选 众联互联网络科技
0