threading.local()
通过threading.local()
可以创建一个线程安全的全局变量,即在一线程中的修改不会影响另一线程。结合代码说明:
通过修改代码验证“名同实不同”:
所以threading.local()
是通过创建“名同实不同”的“全局变量”。
LocalProxy 和 LocalStack
这两个都是基于 werkzeug.local.Local
实现。
werkzeug.local.Local
和threading.local
只有两个不同,一个是前者优先使用Greenlet的ID,其次是线程ID;二是前者实现了一个析构方法(__release_local__
)来析构(删除)创建的werkzeug.local.Local
对象。
总的来说,前者是web升级版的threading.local
. 那么顾名思义,LocalProxy
和LocalStack
分别是线程安全的代理和线程安全的栈。
0x02 上下文
关于上下文,已经有很好的介绍文章了(见文末),我这里只做一些补充。
线程不安全的情况
在单App的情况下,通过current_app修改app配置会影响到其它线程。
为什么要有LocalProxy
按前文所述,通过LocalProxy
拿到的是一个“名同实不同”的变量。例如flask
中的request
, 他就是一个LocalProxy
对象,我们经常需要通过这个变量拿到一些请求参数。这时,将其变成“名同实不同"的全局变量,显然要比在每个视图函数中都传入一个request
参数来得方便。
为什么要有LocalStack
按前文所述,通过LocalProxy
存储的是“名同实不同”的变量。我们已经知道这种“名同实不同”的变量会让我们在不同线程中方便地使用同一名称的变量,但是如果一个线程中有多个变量呢?
只有栈结构才能保存多个 Context 并在其中定位出哪个才是“当前”。
在作为一个简单的网站后台时,一般不会有这种情况,因为一个HTTP请求对于一个request 环境和一个 application 环境。但是,在离线测试的时候,可能会推入栈中多个context。
原文发布时间为:2017-08-15
本文作者:哇咔咔
本文来自云栖社区合作伙伴“Python中文社区”,了解相关信息可以关注“Python中文社区”微信公众号