Flask中请求数据的优雅传递
当一个请求到来时,浏览器会携带很多信息发送发送服务端。在Django中,每一个处理函数都要传入一个request的参数,该参数携带所有请求的信息,也就是服务端程序封装的environ
(不明白该参数可以参见上一篇flask初探之WSGI)。简单示例如下
每一个请求携带的数据都可以从request传入到处理函数中,这种处理方法可以称之为显示传递。
接收请求数据在Flask中有一种更巧妙的实现:当有请求到来时request就会变成一个全局变量,所有的处理函数可以直接使用request这个全局变量,而不需要显示传入参数。简单示例如下:
这种设计减少了每个函数需要传入的参数,比起Django的显示传参更加优雅。
但是这种全局变量也会自己的问题,多线程的情况下同一时间能够处理多个请求,每个处理函数都需要自己的请求信息,如何保证处理函数和请求一一对应呢?Flask主要使用本地线程技术来保证请求信息和处理函数相互的对应。下面主要介绍本地线程技术。
1|0本地线程
在多线程编程中,全局变量不可避免的会竞争,通常使用加锁来解决竞争。此外有一种本地线程
技术可以让每一个线程都拥有自己的私有的变量。比如全局变量a,使用本地线程技术可以让每一个线程对a处理时都是互相隔离的,彼此之间不影响。下面从局部变量、全局变量和本地线程三个例子对比说明本地线程技术。
局部变量
开启多线程,每个子线程完成不同的计算任务,x是线程中的局部变量。
每个子线程都有独立的空间。每次压栈,局部变量x的作用域地址是不同的(线程独享),计算结果互不干扰。
运行结果:
全局变量
当多线程使用全局变量时就会发生抢占和竞争
运行结果:
希望的结果是100,最后却远大于100。原因在于第一个线程将全局变量+1之后,第二个线程在这个基础上继续+1,第三个线程在继续对x+1,每个线程都对全局变量+1,最终结果就不符合预期。
本地线程
本地线程可以避免上面全局变量竞争问题。标准库threading
中就自带本地线程对象。
运行结果:
本质上本地线程对象就是一个字典的子类,为每一个线程创建一个键值对,key是线程id,value是值。当某一个线程操作变量时就是操作自己的id对象的值。
如上例中本地线程是a,可将其看做一个字典a = {"线程id": x}。线程1中a={"123145570172928":44},线程2中a={"123145559662592": 55}。所以各个线程之间虽然引用了同名变量,但实际上是互相不干扰的。
2|0LocalStack
本地栈和本地线程类似的功能,本地线程常用来处理数字或字符串等简单数据结构,维护了{"线程id":值}这样一个关系。本地栈是一个可以当做栈来使用的结构,本质上也是一个字典,结构为{"线程id":{"stack":[]}。这个数据结构的主要是能够使用压栈和出栈等操作,方便先进后出的场景。
简单使用
运行结果:
线程互不干扰
3|0request的线程隔离实现
通过本地线程技术,request虽然是全局变量,但是在每一个线程中都是互相隔离的。
但需要说明的是Flask中并不是使用标准线程库的本地线程对象,因为还需要兼容协程,所以flask使用了werkzeug中的本地线程对象werkzeug.local.Local()
。werkzeug的本地线程对象增加了对Greenlet的优先支持。
werkzeug中本地线程的实现
从import可以看出,首先是从协程导入,如果报错再从线程导入。在__setattr__
函数添加变量时,首先是通过get_ident方法获取了线程id,然后将线程id作为key,value又是一个字典{name:value}。类似于{"线程id":{"name": "value"}}。
__EOF__

本文链接:https://www.cnblogs.com/goldsunshine/p/15890858.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理