Python中上下文管理器解析

在这里插入图片描述

文章目录

  • 基本原理
  • 上下文管理器的工作原理
  • 自定义上下文管理器
    • enter和exit
    • contextlib 模块
  • 异常处理

Python中的上下文管理器(Context Manager)是一种用于管理资源的机制,特别是在文件操作、数据库连接和锁定等场景中非常有用。上下文管理器通过定义__enter__()和__exit__()方法来控制代码块的进入和退出,从而确保资源的正确分配和释放。

基本原理

  • __enter__(self):在进入上下文时执行的代码。
  • __exit__(self, exc_type, exc_value, traceback):在退出上下文时执行的代码。

上下文管理器的工作原理

with open('file.txt', 'r') as file:data = file.read()

其工作流程如下:

  1. 调用上下文管理器对象的 __enter__ 方法。
  2. __enter__ 方法的返回值赋给 as 后面的变量(如上例中的 file)。
  3. 执行 with 块中的代码。
  4. 无论是否发生异常,调用上下文管理器对象的 __exit__ 方法。

当使用with语句时,首先会调用上下文管理器的__enter__()方法。这通常包括一些预处理操作,如打开文件、获取锁等。

在with语句的代码块内执行用户定义的操作。这些操作可以是任何Python代码。

当代码块执行完毕后,会自动调用上下文管理器的__exit__()方法。这通常包括一些清理操作,如关闭文件、释放锁等。

自定义上下文管理器

要实现一个上下文管理器,可以通过以下两种方式:

enter和exit

可以通过实现 __enter____exit__ 方法来自定义上下文管理器。例如:

class MyContextManager:def __enter__(self):print("进入自定义上下文管理器")return selfdef __exit__(self, exc_type, exc_value, traceback):print("退出上下文管理器")if exc_type is not None:print(f"Exception: {exc_type}, {exc_value}")return True  # Suppress the exception# 使用自定义的上下文管理器
with MyContextManager() as manager:print("在上下文管理器中")raise ValueError("发送错误!")

输出为:
在这里插入图片描述

contextlib 模块

Python 提供了 contextlib 模块,帮助简化上下文管理器的创建。特别是contextlib.contextmanager装饰器,可以将一个生成器函数转换为上下文管理器

from contextlib import contextmanager@contextmanager
def my_context():print("进入上下文(装饰器)")try:yieldfinally:print("退出上下文管理器(装饰器)")# 使用生成器函数作为上下文管理器
with my_context():print("在上下文管理器中(装饰器)")

输出为:
在这里插入图片描述
yield是一个关键字,用于实现生成器函数。生成器函数是一种特殊的函数,它返回一个生成器对象,这个对象支持迭代协议,即它有__iter__()和__next__()方法。生成器允许你在每次迭代时按需生成值,而不是一次性生成所有值,这有助于节省内存和提高性能。


想象你有一个工厂,这个工厂生产水果。但是,你不想一次性生产出所有的水果,因为你没有足够的地方来存放它们。你希望按照需求生产,每次只生产一个水果,当有人需要时才生产下一个。

在Python中,yield就像是这个工厂的生产线。当你定义一个函数时,如果函数里面包含了yield,这个函数就变成了一个生成器函数。每次你调用这个生成器函数,它都会给你一个水果,然后停下来,等待下一次请求。

def fruit_factory():yield "苹果"yield "香蕉"yield "橙子"factory = fruit_factory()
print(next(factory))  # 输出 "苹果"
print(next(factory))  # 输出 "香蕉"
print(next(factory))  # 输出 "橙子"

在这里插入图片描述


在Python中,@contextmanager是一个装饰器,位于contextlib模块下。它的主要作用是将一个生成器函数转换为一个上下文管理器,从而可以使用with语句来管理代码块的上下文。使用@contextmanager装饰器,可以简化创建上下文管理器的过程,避免手动编写__enter____exit__方法。

异常处理

上下文管理器还可以处理异常。在with语句中,如果发生异常,上下文管理器的__exit__()方法会被调用,以确保资源的正确释放,即使在异常情况下也能保证资源的安全性。


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

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

相关文章

SpringBoot中MyBatisPlus的使用

MyBatis Plus 是 MyBatis 的增强工具,提供了许多强大的功能,简化了 MyBatis 的使用。下面是在 Spring Boot 中使用 MyBatis Plus 的步骤: 添加依赖:在 Maven 或 Gradle 的配置文件中添加 MyBatis Plus 的依赖。 配置数据源&#…

Linux【安全 02】OpenSSH漏洞修复(离线升级最新版本流程)网盘分享3个安装包+26个离线依赖

OpenSSH离线升级最新版本流程 1. 漏洞信息2. 环境说明3.依赖安装3.1 在线安装3.2 离线安装 4.备份卸载4.1 备份4.2 卸载旧版本 5.安装5.1 zlib5.2 ssl5.3 openssh5.3.1 安装5.3.2 配置 6.脚本整理7.文件资源 本文仅针对CentOS7.8版本,其他版本未测试,安装…

Excel单元格格式无法修改的原因与解决方法

Excel单元格格式无法更改可能由多种原因造成。以下是一些可能的原因及相应的解决方法: 单元格或工作表被保护: 如果单元格或工作表被设置为只读或保护状态,您将无法更改其中的格式。解决方法:取消单元格或工作表的保护。在Excel中…

Hadoop伪分布式安装教程

Hadoop伪分布式安装教程 一、安装背景1.1 软件列表1.2 系统软件列表 二、安装Hadoop2.1 安装 Java 环境2.1.1 前期准备2.1.2 文件传输2.1.3 解压文件2.1.4 配置 jdk 的环境变量2.1.5 输入 java、javac、java -version 命令检验 jdk 是否安装成功 2.2 Hadoop 下载地址[hadoop](h…

一些关于深度聚类以及部分对比学习的论文阅读笔记

目录 资料SwAV问题方法方法的创新点为什么有效有什么可以借鉴的地方聚类Multi-crop 代码 PCL代码 Feature Alignment and Uniformity for Test Time Adaptation代码 SimSiam 资料 深度聚类算法研究综述(很赞,从聚类方法和深度学习方法两个方面进行了总结&#xff0…

基于聚类和回归分析方法探究蓝莓产量影响因素与预测模型研究附录

🌟欢迎来到 我的博客 —— 探索技术的无限可能! 🌟博客的简介(文章目录) 目录 背景数据说明数据来源思考 附录数据预处理导入包以及数据读取数据预览数据处理 相关性分析聚类分析数据处理确定聚类数建立k均值聚类模型 …

《面试笔记》——MySQL终结篇30

三大范式? 第一范式:字段具有原子性,不可再分(字段单一职责) 第二范式:满足第一范式,每行应该被唯一区分,加一列存放每行的唯一标识符,称为主键(都要依赖主…

【Linux】深入解析动静态库:原理、制作、使用与动态链接机制

文章目录 前言:1. 什么是动静态库2. 动静态库的制作和使用3. 动态库的查找问题4. 理解动态库的加载4.1. 站在系统的角度理解4.2. 编址、可执行程序4.3. 动态库动态链接和加载问题 总结: 前言: 在软件开发中,动静态库是两种重要的…

【miniconda】安装miniconda

☆ 问题描述 ubuntu环境下安装miniconda ★ 解决方案 ubuntu环境下安装miniconda 下载miniconda 包 miniconda官网地址:https://docs.conda.io/en/latest/miniconda.html 清华大学镜像地址: https://mirrors.tuna.tsinghua.edu.cn/anaconda/minicon…

Arduino ESP8266模块TFT液晶屏

ESP8266模块 模块实物图: 模块引脚定义: 工作模式选择: FlashBoot启动模式: GPIO15接GND UART固件下载模式: GPIO15接GND, GPIO0接GND 调试串口: URXD/UTXD 可用来下载固件和调试信息输出 模块使能&…

天润融通携手好丽友,打造食品零售行业智能客服新标杆

AI大模型,如何给食品零售行业的客服服务带来质变? 在很多人印象中,食品零售行业是不需要客户服务的。 因为绝大多数食品都是通过经销商、零售商、商场这样的渠道进行销售。所以在食品零售行业,一直都有一句话,叫“渠…

Mac终端operation not permitted问题、禁用和启用SIP(系统完整性保护)

Mac终端operation not permitted问题、禁用和启用SIP(系统完整性保护) 注意: 仅在必要时临时禁用SIP,并尽快重新启用它。在测试完成后不重新启用SIP将使您的计算机容易受到恶意代码的攻击 文章目录 Mac终端operation not permitt…

Spring Boot发送邮件时如何支持定时功能?

如何使用Spring Boot结合AokSend以实现高效邮件发送? 如何高效地进行sendmail发送邮件并支持定时功能是一个值得探讨的问题。本文将详细介绍如何在Spring Boot中实现定时sendmail发送邮件,并结合AokSend工具实现高效邮件发送。 Spring Boot发送邮件&am…

Java程序策——Java连接数据库保姆级教程(超详细步骤)

【Java程序策】——连接数据库 目录 ​编辑 一:在数据库中建立一个表(student表) 1.1:进入mysql 1.2:建立一个“数据库成员” 1.3:建立一个表(student表) 1.4:给表…

【代码随想录】【算法训练营】【第25天】 [216]组合总和III [17] 电话号码的字母组合

前言 思路及算法思维,指路 代码随想录。 题目来自 LeetCode。 day 25,周六,坚持有点困难~ 题目详情 [216] 组合总和III 题目描述 216 组合总和III 解题思路 前提:组合子集问题 思路:回溯算法,剪枝…

【vscode篇】1-VScode设置语言为中文,2-解决中文注释乱码问题。

设置语言为中文 在前端开发中,Visual Studio Code(简称vscode)是一个非常好用的工具,但第一次打开vscode会发现界面为英文,这对很多开发者来说会很不友好(比如我),把界面设置成中文只需要安装一个插件即可&…

《QT从基础到进阶·四十二》QT运行后项目图标,exe图标问题,VS加载.pro文件问题

1、QT图标有时候不能正常显示,不管是加到qrc还是用绝对路径,都无法正常显示,之前是可以的,具体原因目前还不太清楚,我在VS项目——vcpkg——use vcpkg把否改为是就可以了 2、出现无法定位程序输入点的报错&#xff0c…

36. 【Java教程】输入输出流

本小节将会介绍基本输入输出的 Java 标准类,通过本小节的学习,你将了解到什么是输入和输入,什么是流;输入输出流的应用场景,File类的使用,什么是文件,Java 提供的输入输出流相关 API 等内容。 1…

AVL树的介绍与实现

前言 我们上一期介绍了二叉搜索树并做了实现,本期我们来继续学习另一个更优的树即AVL树! 本期内容介绍 什么是AVL树? AVL树的实现 AVL树的性能分析 在正式的介绍AVL树之前,我们先来回忆一下二叉搜索树的特点:左子树的…