Python 的 with 语句可以用来管理资源的自动清理,并替代 try...finally 语句,使代码更简洁易读

Python 的 with 语句可以用来管理资源的自动清理,并替代 try...finally 语句,使代码更简洁易读。

1. with 语句的作用

在 Python 里,with 语句通常用于管理资源,比如文件、数据库连接、网络请求等。
它可以保证无论代码是否执行成功,都会执行必要的清理工作,比如自动关闭文件、断开连接等。

示例:with 语句打开文件,自动关闭:

with open('foo.txt') as fp:content = fp.read()  # 读取文件内容
# 代码运行到这里,文件会自动关闭

在没有 with 的情况下,必须手动关闭文件:

fp = open('foo.txt')
try:content = fp.read()
finally:fp.close()  # 确保文件被关闭

对比可见,with 语句更简洁,不用显式调用 close()


2. with 的底层原理——上下文管理器

with 之所以能自动管理资源,是因为它依赖上下文管理器(context manager)
上下文管理器是实现了 __enter____exit__ 方法的对象。

  • __enter__(): 进入 with 代码块时调用,可以返回一个资源对象。
  • __exit__(): 退出 with 代码块时调用,处理异常并进行清理工作。

示例:手写一个上下文管理器

import randomclass DummyContext:def __init__(self, name):self.name = namedef __enter__(self):"""进入上下文管理器,返回带随机后缀的 name"""return f'{self.name}-{random.random()}'def __exit__(self, exc_type, exc_val, exc_tb):"""退出上下文管理器时,执行清理操作"""print('Exiting DummyContext')with DummyContext('foo') as name:print(f'Name: {name}')

执行结果:

Name: foo-0.123456789
Exiting DummyContext

可以看到 __exit__ 方法无论有没有异常,都会在退出时执行


3. with 语句的实际用途

(1)替代 try...finally 进行资源管理

在管理网络连接、数据库连接等资源时,通常会使用 try...finally 语句来确保即使发生异常,资源也会被正确释放
with 语句可以让代码更简洁。

传统 try...finally 方式:

conn = create_conn(host, port)
try:conn.send_text('Hello, world!')
except Exception as e:print(f'Unable to use connection: {e}')
finally:conn.close()  # 确保连接被关闭

使用 with 语句简化:

class create_conn_obj:"""创建连接对象,并在退出上下文时自动关闭"""def __init__(self, host, port):self.conn = create_conn(host, port)def __enter__(self):return self.conndef __exit__(self, exc_type, exc_value, traceback):self.conn.close()  # 退出时自动关闭return False  # 让异常继续传播(如果发生异常)with create_conn_obj(host, port) as conn:conn.send_text('Hello, world!')

with 代码块结束时,无论是否有异常,连接都会自动关闭。


(2)用于忽略特定异常

有时候,我们可能想忽略某些特定的异常,让代码继续执行。例如:

try:close_conn(conn)
except AlreadyClosedError:pass  # 忽略异常

这种写法虽然简单,但会导致 try...except 语句分散在代码各处,不易维护。

可以使用 上下文管理器封装忽略异常的逻辑

class ignore_closed:"""忽略 AlreadyClosedError 异常"""def __enter__(self):passdef __exit__(self, exc_type, exc_value, traceback):if exc_type == AlreadyClosedError:return True  # 返回 True,表示异常已被处理,不再传播return False  # 其他异常继续传播with ignore_closed():close_conn(conn)  # 即使连接已关闭,也不会抛出错误

如果 close_conn(conn) 触发 AlreadyClosedError,它会被 ignore_closed 处理掉,而不会终止程序。

实际上,Python 标准库 contextlib 提供了 suppress() 方法,可以直接用:

from contextlib import suppresswith suppress(AlreadyClosedError):close_conn(conn)  # 忽略异常

这样代码更加简洁。


4. contextmanager 装饰器简化上下文管理器

如果只是为了实现简单的上下文管理器,不必写一个完整的类,可以使用 contextlib.contextmanager 装饰器,用函数+yield 来实现。

示例:

from contextlib import contextmanager@contextmanager
def create_conn_obj(host, port):"""创建连接对象,并在退出上下文时自动关闭"""conn = create_conn(host, port)try:yield conn  # 这里返回 conn,类似于 __enter__finally:conn.close()  # 退出时关闭连接,类似于 __exit__with create_conn_obj(host, port) as conn:conn.send_text('Hello, world!')

yield 之前的代码在进入 with 代码块时执行(类似 __enter__),
yield 之后的代码在退出 with 代码块时执行(类似 __exit__)。
相比手写类,这个方法更加简洁


总结

  1. with 语句用于自动管理资源,替代 try...finally,代码更简洁。
  2. 上下文管理器__enter____exit__)可以实现 with 语句的功能,比如自动关闭文件、数据库连接、网络请求
  3. with 可以用于异常处理,例如:
    • 替代 try...finally 进行资源清理
    • 忽略特定异常
  4. @contextmanager 装饰器可以简化上下文管理器,让代码更优雅。

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

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

相关文章

栈回溯基础

指令集区分 thumb指令集 长度:thumb指令通常是 16 位。特点:thumb 指令集是为了压缩指令集长度减少程序占用空间。对齐方式:2字节对齐,存放 thumb 指令的地址一般会被1,设置为奇数,用于表示地址上存放的是…

Pytorch论文实现之GAN-C约束鉴别器训练自己的数据集

简介 简介:这次介绍复现的论文主要是约束判别器的函数空间,作者认为原来的损失函数在优化判别器关于真样本和假样本的相对输出缺乏显式约束,因为在实践中,在优化生成器时,鉴别器对生成样本的输出会增加,但对真实数据保持不变,而优化鉴别器会导致其对真实数据的输出增加…

Pyecharts系列课程06——热力图(Heatmap)

1. 基础使用 热力图是一种用于展示数据分布的密度或热度的图表,通过颜色深浅来表示数值大小。 a. 简单示例 我们先来看一个简单示例: 简单示例 from pyecharts.charts import HeatMapx_data = ["分类1", "分类2", "分类3"] y_data

交换路由——控制VLAN之间通信

项目 最近一段时间,A公司发现划分VLAN之后,网速提高很多,发生拥堵的情况消失了.但是,部门之间不能互联,也给办公室带来不便.公司要求项目实施各VLAN内主机互通。 部门 VLAN 名称 端口范围 网络ID 计算机 市场部 VLAN 10 shichang f0/1-f/010 192.168.10.0/24 pc0,pc…

使用 Redis 实现 RBAC 权限管理

1. 什么是 RBAC? RBAC(Role-Based Access Control,基于角色的访问控制)是一种常见的权限管理模型,它通过用户(User)、角色(Role)、权限(Permission&#xff…

qt-C++笔记之QGraphicsScene和 QGraphicsView中setScene、通过scene得到view、通过view得scene

qt-C++笔记之QGraphicsScene和 QGraphicsView中setScene、通过scene得到view、通过view得scene code review! 文章目录 qt-C++笔记之QGraphicsScene和 QGraphicsView中setScene、通过scene得到view、通过view得scene1.`setScene` 方法2.通过 `scene` 获取它的视图 (`views()`)…

DeepSeek频繁宕机应对方案

第三方监测显示,38%的企业因AI工具不稳定错失热点流量(Gartner 2025)。当竞品1小时内发布300篇行业内容时,你可能还在为「服务器繁忙」提示焦头烂额。147SEO系统通过智能容错机制,帮助某本地生活平台稳定输出580篇地域…

CentOS/RHEL如何更换国内Yum源

在国内使用CentOS或RHEL系统时,默认的Yum源是国外的,这可能导致软件包的下载速度慢,甚至出现连接超时的问题。为了解决这个问题,我们可以将Yum源切换到国内的镜像源,从而大大提高软件包的下载速度和稳定性。 本文将详…

cs224w课程学习笔记-第2课

cs224w课程学习笔记-第2课 传统图学习 前言一、节点任务1、任务背景2、特征节点度3、特征节点中心性3.1 特征向量中心性(Eigenvector Centrality)3.2 中介中心性(Betweenness Centrality)3.3 接近中心性(Closeness Cen…

【设计模式】【结构型模式】代理模式(Proxy)

👋hi,我不是一名外包公司的员工,也不会偷吃茶水间的零食,我的梦想是能写高端CRUD 🔥 2025本人正在沉淀中… 博客更新速度 👍 欢迎点赞、收藏、关注,跟上我的更新节奏 🎵 当你的天空突…

平板作为电脑拓展屏

有线串流(速度更快) spacedesk 打开usb对安卓的连接 用usb线直接连接电脑和平板 无线串流(延迟高,不推荐) todesk pc和手机端同时下载软件,连接后可以进行远程控制或扩展屏幕 spacedesk 连接到同一个…

[文末数据集]ML.NET库学习010:URL是否具有恶意性分类

文章目录 ML.NET库学习010:URL是否具有恶意性分类项目主要目的和原理项目概述主要功能和步骤总结数据集地址ML.NET库学习010:URL是否具有恶意性分类 项目主要目的和原理 项目主要目的: 本项目的目的是通过分析URL的特征,构建一个机器学习模型来判断给定的URL是否具有恶意…

Zotero PDF Translate插件配置百度翻译api

Zotero PDF Translate插件可以使用几种翻译api,虽然谷歌最好用,但是由于众所周知的原因,不稳定。而cnki有字数限制,有道有时也不行。其他的翻译需要申请密钥。本文以百度为例,进行申请 官方有申请教程: Zot…

具身智能在智能巡检机器人中的应用——以开关柜带电操作机器人为例

随着机器人技术和人工智能的迅速发展,具身智能在各行业的应用日益广泛,尤其是在电力行业中的智能巡检领域。传统的电力巡检和维护工作通常需要人工操作,存在着高温、高压、强电磁场等危险环境,且效率较低。开关柜带电操作机器人作…

网络工程师 (43)IP数据报

前言 IP数据报是互联网传输控制协议(Internet Protocol,IP)的数据报格式,由首部和数据两部分组成。 一、首部 IP数据报的首部是控制部分,包含了数据报传输和处理所需的各种信息。首部可以分为固定部分和可变部分。 固定…

【SpringBoot苍穹外卖】debugDay0 打开前端页面

在某一天学完后,电脑关机,再打开啥都忘了,记起来一点点,前端页面打不开,后端控制台一直循环出错。原来是下面这样哈哈。 查看端口是否被别的程序占用的操作步骤 winR输入cmd打开命令行 netstat -ano | findstr "8…

docker 运行 芋道微服务

jar包打包命令 mvn clean install package -Dmaven.test.skiptrue创建文件夹 docker-ai 文件夹下放入需要jar包的文件夹及 docker-compose.yml 文件 docker-compose.yml 内容:我这里的是ai服务,所以将原先的文件内容做了变更,你们需要用到什…

MySQL-事务隔离级别

事务有四大特性(ACID):原子性,一致性,隔离性和持久性。隔离性一般在事务并发的时候需要保证事务的隔离性,事务并发会出现很多问题,包括脏写,脏读,不可重复读,…

【MediaTek】 T750 openwrt-23.05编 cannot find dependency libexpat for libmesode

MediaTek T750 T750 采用先进的 7nm 制程,高度集成 5G 调制解调器和四核 Arm CPU,提供较强的功能和配置,设备制造商得以打造精巧的高性能 CPE 产品,如固定无线接入(FWA)路由器和移动热点。 MediaTek T750 平台是一款综合的芯片组,集成了 5G SoC MT6890、12nm 制程…

五十天精通硬件设计第32天-S参数

系列文章传送门 50天精通硬件设计第一天-总体规划-CSDN博客 目录 1. S参数基础 2. S参数在信号完整性中的作用 3. 单端 vs. 差分S参数 4. S参数的关键特性 5. S参数的获取与使用 6. S参数分析中的常见问题 7. 实际案例:PCIe通道分析 8. 工具推荐 总结 信号完整性中…