Flask中使用with语句手动加载应用上下文

在 Flask 中,with app.app_context(): 手动加载应用上下文,使代码块可以访问 Flask 全局对象(如 current_appg),即使代码不在请求中运行。


1. 为什么需要手动加载应用上下文?

在 Flask 中,某些操作(如访问 current_appg)必须在应用上下文(Application Context)中运行,否则会报错:

from flask import Flask, current_appapp = Flask(__name__)print(current_app.name)  # ❌ 报错:RuntimeError: Working outside of application context

错误原因:

  • current_app线程隔离的全局变量,只有在 Flask 应用上下文内才能访问。
  • 默认情况下,Flask 只有在处理 HTTP 请求时才会自动推送应用上下文

2. with app.app_context() 解决问题

可以用 with app.app_context(): 手动创建应用上下文,避免错误:

with app.app_context():print(current_app.name)  # ✅ 正常输出 "__main__"

执行流程:

  1. app.app_context() 创建一个应用上下文对象 ctx
  2. ctx.push() 激活应用上下文,使 current_app 可用。
  3. 执行 with 代码块。
  4. ctx.pop() 退出上下文,释放资源。

3. app.app_context() 的底层原理

Flask 通过 AppContext(应用上下文类)来管理 current_appg

# Flask app.app_context() 底层实现(简化版)
class AppContext:def __init__(self, app):self.app = appdef push(self):_app_ctx_stack.push(self)  # 进入应用上下文_app_ctx_globals.set({})  # 初始化 `g`def pop(self):_app_ctx_stack.pop()  # 退出应用上下文

调用 app.app_context() 其实是创建 AppContext 实例,并使用 push() 进入应用上下文。

Flask 的 with 语法糖:

@contextmanager
def app_context(self):ctx = self.app_context_class(self)try:ctx.push()yield ctxfinally:ctx.pop()

这就是为什么 with app.app_context(): 自动管理上下文,不需要手动 push/pop()


4. with app.app_context() 的应用场景

(1)后台任务

后台任务(如 Celery 任务、定时任务)通常不在 Flask 请求上下文中,需要手动加载应用上下文:

def background_task():with app.app_context():print(current_app.config["SECRET_KEY"])  # ✅ 访问 Flask 配置

(2)Python 交互式 Shell

直接运行 python 进入交互模式,默认没有应用上下文

from myapp import app
app.config["DEBUG"]  # ❌ 报错

解决方案:

with app.app_context():print(app.config["DEBUG"])  # ✅

(3)数据库操作

如果数据库操作不在请求中,如脚本导入数据:

from myapp import app, db, Userwith app.app_context():user = User(name="Alice")db.session.add(user)db.session.commit()

如果不加 app.app_context()db.session找不到当前应用上下文,导致错误。


5. app.app_context() vs. app.test_request_context()

方法作用适用场景
app.app_context()仅创建应用上下文后台任务、数据库操作、Shell 调试
app.test_request_context()创建应用上下文 + 请求上下文单元测试、模拟请求

示例:

with app.test_request_context('/hello?name=Alice'):from flask import requestprint(request.args['name'])  # ✅ Alice

如果只使用 app.app_context()request 仍然不可用


6. 结论

  1. Flask 运行时需要上下文(应用上下文、请求上下文)来管理 current_appg 等对象。
  2. 默认情况下,应用上下文只在 HTTP 请求期间存在,在脚本、后台任务中访问 current_app 会报错。
  3. with app.app_context(): 手动创建应用上下文,确保 current_app 可用
  4. 底层原理:app.app_context() 创建 AppContextpush() 进入栈,pop() 退出栈

如果你的 Flask 代码不在 HTTP 请求中运行,比如后台任务、脚本、交互式 Shell,就需要手动加载应用上下文! 🚀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/34740.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在Ubuntu上构建编译LLVM和ISPC,以及Ubuntu上ISPC的使用方法

之前一直在 Mac 上使用 ISPC,奈何核心/线程太少了。最近想在 Ubuntu 上搞搞,但是 snap 安装的 ISPC不知道为什么只能单核,很奇怪,就想着编译一下,需要 Clang 和 LLVM。但是 Ubuntu 很搞,他的很多软件版本是…

特殊的数字排序

0特殊的数字排序 - 蓝桥云课 问题描述 小明被挑选去参加一个ACM比赛。他的任务是解决一个很特别的问题:给定一个整数数组,但是只能通过交换任意两个数的方式来排序。听起来很简单对吗?但是这个问题的难点在于,只有某些数字是可以…

汽车感性负载-智能高边钳位能量计算

随着汽车电子技术的发展,新的电子电气架构下,越来越多的执行部件在车身出现,比如电磁阀、风机、水泵、油泵、雨刮继电器等常用的执行器, 它们一般都表现为感性特点。驱动这些负载的最简单和最常见的方法是将它们连接到高边侧开关(…

量化交易学习笔记02:双均线策略

双均线策略示例 个股:中国平安 回测日期:2022-5-1至2023-5-1 短均线:5天 长无线:10天 代码: def initialize(context):# 初始化此策略# 设置我们要操作的股票池, 这里我们只操作一支股票# """标的&qu…

利用余弦相似度在大量文章中找出抄袭的文章

我前面的2篇文章分别讲了如果利用余弦相似度来判断2篇文章的相似度,来确定文章是否存在抄袭,和余弦相似度的原理,即余弦相似度到底是怎么来判断文章的相似性高低的等等。这一篇再说下,对于文章字数多和大量文章时,如果…

在 Kaggle 中绘制中文乱码解决

在 Kaggle 中绘制中文时,需要设置 Matplotlib 的字体,否则中文会显示为乱码。可以使用 SimHei(黑体)或 Microsoft YaHei(微软雅黑)。 解决方案 使用 matplotlib 设置中文字体在 Kaggle 安装 SimHei 字体 …

在 Ubuntu 服务器上使用宝塔面板搭建博客

📌 介绍 在本教程中,我们将介绍如何在 Ubuntu 服务器 上安装 宝塔面板,并使用 Nginx PHP MySQL 搭建一个博客(如 WordPress)。 主要步骤包括: 安装宝塔面板配置 Nginx PHP MySQL绑定域名与 SSL 证书…

Linux线程

1.线程概念 在一个程序里的一个执行路线就叫做线程(thread),更准确定义:线程是一个进程内部的控制序列 进程至少有一个执行路线,线程在进程内部运行,本质是在进程地址空间内运行,在Linux系统中,CPU眼中&a…

【TI MSPM0】GPIO学习

一、文件样例查找 以GPIO软件轮询为例 下面的四个文件夹分别为不同开发环境提供支持 二、工程导入 1.点击file-点击import project 2.点击browse 3.找到对应的文件打开,选择 推荐使用ticlang,能够提供更加优化的效率 点击finish 三、工程学习 1.readme 文件 &a…

二叉树的基本操作与实现:C语言深度剖析

目录 代码整体框架 1. #define _CRT_SECURE_NO_WARNINGS 2. 头文件引入 3. typedef int BTtype; 4. 二叉树节点结构体定义 二叉树的创建 1. BuyNode 函数 2. CreatNode 函数 二叉树的遍历 前序遍历 中序遍历 后序遍历 二叉树属性的计算 节点个…

深入解析 Latent Diffusion Model(潜在扩散模型,LDMs)(代码实现)

深入解析 Latent Diffusion Model:从传统 Diffusion Model 到高效图像生成的进化 近年来,生成模型在图像合成领域取得了显著进展,其中 Diffusion Model(扩散模型,DMs)以其出色的生成质量和理论上的稳健性逐…

线性回归原理推导与应用(五):波士顿房价预测实战

波士顿房价是一个非常经典的多元线性回归入门案例数据集。波士顿房价预测数据集包含了可能会影响房价的十三个因素,并给出了实际的房价(单位为万美元) 波士顿房价数据集数据集下载地址:https://www.kaggle.com/datasets/altavish…

基于CATIA二次开发的低音炮腔体容积精准计算技术详解

一、功能概述 本工具通过PySide6与CATIA V5深度集成,实现了低音炮上下腔体内体积的自动化测量系统。系统采用三维实体建模法进行容积计算,相较于传统手工计算方式,精度提升可达0.5%。主要功能模块包括: 壳体特征自动识别动态草图…

向量数据库原理及选型

向量数据库 什么是向量什么是向量数据库原理应用场景 向量数据库的选型主流向量数据库介绍向量数据库对比主流向量数据库对比表 选型建议 什么是向量 向量是一组有序的数值,表示在多维空间中的位置或方向。向量通常用一个列或行的数字集合来表示,这些数…

IE代理切换器v1.2免费版

虽然IE浏览器已经过时了,但很多其他浏览器,比如谷歌浏览器的代理服务器设置,都还是基于IE浏览器来进行设置的,如果你的工作场景需要切换不同的代理服务器来访问网络,那这款工具适合你,目前该工具可以实现IE…

模运算的艺术:从基础到高阶的算法竞赛应用

在算法竞赛中,模运算(取模运算)是一个非常重要的概念,尤其在处理大数、防止溢出、以及解决与周期性相关的问题时。C 中的模运算使用 % 运算符,但它的行为和使用场景需要特别注意。 1. 模运算的基本概念 模运算是指求一…

SpringBoot前后端不分离,前端如何解析后端返回html所携带的参数

有一个SpringBoot实现的前后端不分离项目,当前端跳转某个界面时,比如下面的菜单树按钮,后端在返回页面menuTree.html时,还携带了一个参数角色roleId,以便打开菜单树,还要根据这个角色查询对应的分配授权的菜…

操作系统八股文整理(一)

操作系统八股文整理 一、进程和线程的区别二、进程与线程的切换过程一、进程切换进程切换的步骤: 二、线程切换线程切换的步骤: 三、进程切换与线程切换的对比四、上下文切换的优化 三、系统调用一、系统调用的触发二、从用户空间切换到内核空间三、执行…

卷积神经网络(CNN)之 EfficientNet

在深度学习领域,模型的计算效率与性能之间的平衡一直是一个核心挑战。随着卷积神经网络(CNN)在图像分类、目标检测等任务中取得显著成果,模型的复杂度和计算需求也急剧增加。2019年,Google Research 提出的 EfficientN…

leetcode0031 下一个排列-medium

1 题目: 下一个排列 官方标定难度:中等 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如,arr [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一…