Flask 上下文是什么 ?

简介: Flask 上下文是什么 ?

哈喽大家好,我是咸鱼。今天我们来聊聊什么是 Flask 上下文

咸鱼在刚接触到这个概念的时候脑子里蹦出的第一个词是 CPU 上下文

今天咸鱼希望通过这篇文章,让大家能够对 Flask 上下文设计的初衷以及应用有一个基本的了解

Flask 上下文

我们在使用 Flask 开发 web 程序的时候,通常会面临下面的情况
image.png
假设同一时间内有三台客户端(或浏览器)向 web 服务器发送了请求,那么 Flask 应用是如何分辨出这三个请求属于哪台客户端(或浏览器)并返回正确的响应的呢?

聪明的你结合文章题目很快就想到了——Flask 上下文

在 Flask 中,通过本地线程技术来实现上下文隔离。本地线程是一种轻量级的线程,它可以在同一个进程中创建多个线程,并且每个线程拥有独立的堆栈和寄存器等资源,因此可以并发地执行多个任务

1、接收到请求的时候,Flask 会为每个请求创建一个 Flask 上下文对象,这个上下文对象包含了一些全局或者请求级别的变量

2、处理请求的时候,Flask 会为这个请求的上下文对象分配或创建一个本地线程,这样就可以在处理请求的各个环节当中通过本地线程来访问这个请求的上下文对象了

3、请求处理完毕之后,Flask 会将请求上下文对象从当前线程中删除并销毁。这样就能保证每次请求都是独立的,避免了线程安全问题

结合上面的例子我们得知,首先 Flask 应用会为这三个请求分配(或创建)到不同的线程中,然后创建与三个请求对应的三个 Flask 上下文对象(应用上下文和请求上下文)并存储到本地线程当中

到这里有小伙伴可能会问,Flask 应用是如何区分这三个请求上下文的呢?

Flask 使用的上下文是通过 werkzeug.local 模块中的 Local 类实现的。Local 对象实际上是一个字典,它的键是线程 ID,值是该线程对应的上下文对象

所以说,Flask 通过线程 ID 来区分不同的请求上下文

两种上下文

现在我们知道了,Flask 会自动为每个请求创建一个专属的独一无二的环境,称为上下文

这个上下文环境包含了一些全局级别和请求级别的变量,可以在请求处理的整个过程当中使用

也就是说,Flask 上下文由两部分组成——应用上下文和请求上下文
image.png
应用上下文(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() 上下文管理器来实现
image.png

  • 手动激活请求上下文

image.png

总的来说,无论使用哪种方式,激活 Flask 上下文的目的都是为了能够在处理请求的过程中访问请求上下文,并且在请求处理完毕后,正确地销毁请求上下文

感谢阅读,喜欢作者就动动小手[一键三连],这是我写作最大的动力

相关文章
|
7月前
|
存储 中间件 数据库连接
揭开Flask上下文管理的神秘面纱
【4月更文挑战第15天】Flask的上下文管理涉及应用上下文和请求上下文,简化了Python Web开发。应用上下文存储全局数据,如数据库连接,而请求上下文处理请求相关数据,如URL参数。通过全局变量`current_app`和`request`访问上下文信息。上下文管理在视图函数、中间件和扩展开发中发挥作用,提高代码效率和应用可扩展性。理解这一机制有助于提升Flask开发技能。
高频面试题之Flask框架的上下文
Flask框架中分为2种上下文: 请求上下文(request context)和应用上下文(app context) 一般面试的问点在于:两种上下文是什么? 有什么区别? 什么场景下使用?
|
消息中间件 数据采集 Java
Flask嵌套启动子线程如何读取请求上下文?
Flask嵌套启动子线程如何读取请求上下文?
239 0
|
存储 JSON 前端开发
Flask 扫盲系列-Flask 上下文
上一次我们做了一个简单的在线股票走势网站,今天我们来继续完善下网站功能,并学习些新的 Flask 知识点。
Flask 扫盲系列-Flask 上下文
|
数据库 Python
Python Flask SQLAlchemy上下文介绍
如果您打算仅使用一个应用程序(app),则可以在很大程度上跳过本文。只要将您的应用程序传递给SQLAlchemy 构造函数,就可以设置好了。但是,如果要使用多个应用程序,或者要在要读取的功能中动态创建该应用程序。
268 0
|
存储 数据库连接 数据库
小白学Flask第八天| Flask上下文和请求钩子
小白学Flask第八天| Flask上下文和请求钩子
221 0
|
存储 Python Sentinel
Flask的上下文管理
庭院深深深几许,杨柳堆烟,帘幕无重数。玉勒雕鞍游冶处,楼高不见章台路。 雨横风狂三月暮,门掩黄昏,无计留春住。泪眼问花花不语,乱红飞过秋千去。 一、 通过Threading的local实现的本地存储隔离 当我们开启多线程来执行func函数,通过自定义...
1919 0
|
Python
(搬运以学习)flask 上下文的实现
引言 本文主要梳理了flask的current_app, request, session, g的实现原理 源码说明 本文使用flask 0.5 版本 application context 和request context flask有两个context: application context和...
1279 0