Flask 上下文是什么 ?
哈喽大家好,我是咸鱼。今天我们来聊聊什么是 Flask 上下文
咸鱼在刚接触到这个概念的时候脑子里蹦出的第一个词是 CPU 上下文
今天咸鱼希望通过这篇文章,让大家能够对 Flask 上下文设计的初衷以及应用有一个基本的了解
Flask 上下文
我们在使用 Flask 开发 web 程序的时候,通常会面临下面的情况
假设同一时间内有三台客户端(或浏览器)向 web 服务器发送了请求,那么 Flask 应用是如何分辨出这三个请求属于哪台客户端(或浏览器)并返回正确的响应的呢?
聪明的你结合文章题目很快就想到了——Flask 上下文
在 Flask 中,通过本地线程技术来实现上下文隔离。本地线程是一种轻量级的线程,它可以在同一个进程中创建多个线程,并且每个线程拥有独立的堆栈和寄存器等资源,因此可以并发地执行多个任务
1、接收到请求的时候,Flask 会为每个请求创建一个 Flask 上下文对象,这个上下文对象包含了一些全局或者请求级别的变量
2、处理请求的时候,Flask 会为这个请求的上下文对象分配或创建一个本地线程,这样就可以在处理请求的各个环节当中通过本地线程来访问这个请求的上下文对象了
3、请求处理完毕之后,Flask 会将请求上下文对象从当前线程中删除并销毁。这样就能保证每次请求都是独立的,避免了线程安全问题
结合上面的例子我们得知,首先 Flask 应用会为这三个请求分配(或创建)到不同的线程中,然后创建与三个请求对应的三个 Flask 上下文对象(应用上下文和请求上下文)并存储到本地线程当中
到这里有小伙伴可能会问,Flask 应用是如何区分这三个请求上下文的呢?
Flask 使用的上下文是通过 werkzeug.local
模块中的 Local
类实现的。Local
对象实际上是一个字典,它的键是线程 ID,值是该线程对应的上下文对象
所以说,Flask 通过线程 ID 来区分不同的请求上下文
两种上下文
现在我们知道了,Flask 会自动为每个请求创建一个专属的独一无二的环境,称为上下文
这个上下文环境包含了一些全局级别和请求级别的变量,可以在请求处理的整个过程当中使用
也就是说,Flask 上下文由两部分组成——应用上下文和请求上下文
应用上下文(application context)
当一个 Flask 应用启动时,会自动创建一个应用上下文对象。这个应用上下文对象表示整个应用的运行环境,用于存储应用全局的变量和配置(应用配置、数据库连接信息等)
对于每个请求来说,应用上下文对象会在当前请求处理之前创建,并且会一直存在到请求处理完毕之后才被销毁。这意味着,应用上下文对象可以在整个请求生命周期内共享数据
请求上下文(request context)
当请求到达 Flask 应用的时候,每一个请求都会有一个专属的请求上下文环境,用于存储请求相关的变量和信息(请求路径、请求方法、请求参数等等)
应用上下文和请求上下文的区别
可以看到,应用上下文是全局的,表示整个 Flask 应用的运行环境,而请求上下文是针对每个请求独立的,表示该请求的运行环境
在应用程序的整个生命周期中,应用上下文只有一个,而且存在于应用的整个生命周期中。而请求上下文会随着请求的到来而动态创建和销毁
对于每个请求来讲,应用上下文是每个请求共享的,请求上下文是每个请求独有的
举个简单的例子,比如说有一家大型超市(Flask 应用),每当有顾客来超市买东西的时候(相当于请求到达 Flask 应用),店员就会为每个顾客分配一个购物车(本地线程)
这个购物车里面存放了每个顾客的商品、折扣券(请求上下文)等等。购物车里面的东西是每个顾客专属的、独有的(不同请求的请求上下文是独立的)
当顾客消费完毕之后,购物车里面的东西就会清空,店员就会回收这些购物车,等待分配给下一个顾客使用(请求处理完毕之后将请求上下文对象从当前线程中删除并销毁,并后续为新到的请求分配线程)
而这个超市里面的电梯、货架以及商品(应用上下文)都是每个顾客共享的(应用上下文是每个请求共享的)
当超市关门的时候,电梯、货架以及商品就不能够对外使用了(应用上下文存在于应用的生命周期中)
Flask 上下文激活
Flask 上下文可以分为自动激活和手动激活两种方式
自动激活
自动激活是指 Flask 在处理请求时自动激活应用上下文和请求上下文,无需手动干预,这样可以避免在代码中频繁手动创建和销毁上下文对象,使得代码更加简洁
下面这些情况中,Flask 会自动激活应用上下文:
-
使用 flask run 命令启动程序时
-
使用旧命令
app.run()
启动程序时 -
执行使用
@app.cli.command()
装饰器注册 flask 命令时 -
使用 flask shell 命令启动 python shell 时
当请求进入时,Flask 会自动激活请求上下文
手动激活
在一些特殊情况下需要手动创建或激活上下文对象
例如在使用 Flask 提供的测试客户端进行单元测试时,需要手动创建应用上下文和请求上下文,并在测试完成后手动销毁,以保证测试环境的隔离性
-
手动激活应用上下文
在 Flask 中,手动激活应用上下文可以通过使用 app.app_context()
上下文管理器来实现
-
手动激活请求上下文
总的来说,无论使用哪种方式,激活 Flask 上下文的目的都是为了能够在处理请求的过程中访问请求上下文,并且在请求处理完毕后,正确地销毁请求上下文
感谢阅读,喜欢作者就动动小手[一键三连],这是我写作最大的动力