python中的with是做什么的,有什么作用,什么时候需要用到with

📌 Python 中的 with 语句:作用 & 什么时候用

1️⃣ with 是干嘛的?

with 主要用来 自动管理资源,确保资源(文件、数据库连接等)在使用完后能自动释放,避免资源泄露问题。

换句话说:

  • 不用 with:你要自己手动释放资源,容易忘记,出 bug。
  • 用了 with:Python 会自动帮你释放资源,不用操心。

2️⃣ 什么时候需要 with

凡是涉及
打开文件
数据库连接
网络请求
多线程锁
临时性资源管理

这些场景都应该用 with


3️⃣ 举例说明

(1)文件操作

不使用 with,容易忘记关闭文件

file = open("data.txt", "r")
data = file.read()
file.close()  # 🔴 你必须手动关闭文件

如果 忘了 file.close(),可能会导致 文件一直占用,影响其他程序访问。

使用 with,自动关闭文件

with open("data.txt", "r") as file:data = file.read()  # ✅ 读完后,Python 自动关闭文件

with 结束后,文件 file 会自动关闭!


(2)数据库操作

不使用 with,可能忘记关闭数据库连接

import sqlite3conn = sqlite3.connect("example.db")  
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
data = cursor.fetchall()
conn.close()  # 🔴 必须手动关闭连接

如果程序出错,中途 return 了,conn.close() 可能不会执行,导致数据库连接泄露!

使用 with,自动管理数据库连接

import sqlite3with sqlite3.connect("example.db") as conn:cursor = conn.cursor()cursor.execute("SELECT * FROM users")data = cursor.fetchall()  # ✅ 退出 `with` 代码块时,数据库连接自动关闭!

好处:

  • 不用手动 close(),更安全
  • 即使发生异常,with 也会自动关闭数据库

(3)网络请求

不使用 with,请求未关闭

import requestsresponse = requests.get("https://www.example.com")
data = response.text
response.close()  # 🔴 必须手动关闭连接

如果忘了 response.close(),可能会占用网络资源,影响其他请求。

使用 with,自动关闭请求

import requestswith requests.get("https://www.example.com") as response:data = response.text  # ✅ 退出 `with`,自动关闭请求

(4)多线程锁

多线程编程中,我们需要使用 Lock 来保证数据安全。
但如果忘记释放 lock,程序可能会死锁!

使用 with,确保锁释放

import threadinglock = threading.Lock()with lock:  # ✅ 进入 `with`,加锁print("线程安全的代码")
# ✅ 退出 `with`,自动释放锁

4️⃣ with 语法是如何工作的?

with 其实是调用对象的 __enter__()__exit__() 方法,确保资源正确释放:

class MyResource:def __enter__(self):print("资源已获取")return selfdef __exit__(self, exc_type, exc_val, exc_tb):print("资源已释放")with MyResource():print("使用资源中...")

输出:

资源已获取
使用资源中...
资源已释放

结论: 只要 with 结束,Python 自动调用 __exit__() 释放资源,不用手动操作。


5️⃣ 结论

with 主要用于 自动管理资源,避免手动释放资源的麻烦。
避免资源泄露,减少 bug,即使代码中途出错,也能自动清理资源
常用于:

  • 文件操作
  • 数据库连接
  • 网络请求
  • 多线程锁
  • 临时资源管理

💡 记住:凡是涉及“打开 -> 使用 -> 关闭”的场景,都应该用 with 🚀


📌 with 结束的时机是什么时候?

with 语句的结束时机,简单来说,就是**with 代码块执行完毕**,或者with 代码块中发生异常时。

具体来说,with 语句在退出代码块时,会触发资源的自动清理,也就是调用 __exit__() 方法。


1️⃣ 具体的结束时机

情况 1:正常执行完代码块

如果 with 代码块里的代码正常执行完,就会自动调用 __exit__() 方法释放资源,with 语句结束。

🔹 示例:文件操作

with open("test.txt", "w") as f:f.write("Hello, world!")  # ✅ 正常执行完 `write`
# `with` 结束,文件自动关闭

结束时机: f.write() 执行完,with 退出,文件自动关闭。


情况 2:发生异常,with 也会立即结束

如果 with 代码块里发生异常with 语句会立刻调用 __exit__() 进行清理,然后抛出异常(除非 __exit__() 处理了异常)。

🔹 示例:发生异常

try:with open("test.txt", "w") as f:f.write("Hello, world!")1 / 0  # ❌ 人为制造异常
except ZeroDivisionError:print("发生错误,文件已经关闭")

结束时机: 1 / 0 抛出异常时,with 立刻结束,文件自动关闭。


情况 3:return 也会触发 with 结束

如果 with 代码块里遇到 returnbreakcontinuewith 也会立即结束,并释放资源。

🔹 示例:return 触发 with 结束

def write_file():with open("test.txt", "w") as f:f.write("Hello, world!")return  # ✅ `return` 触发 `with` 结束

结束时机: return 触发 with 结束,文件自动关闭。


2️⃣ with 结束的底层原理

with 语句执行时,它的工作流程如下:

  1. 进入 with:调用 __enter__() 方法,获取资源。
  2. 执行代码块:执行 with 代码块里的内容。
  3. 退出 with
    • 正常结束:执行 __exit__(),释放资源。
    • 发生异常
      • 如果 __exit__() 处理异常,则 with 正常结束。
      • 如果 __exit__() 没有处理异常,异常会继续向上抛出。

🔹 示例:自定义 with 语句行为

class MyContext:def __enter__(self):print("进入 `with` 语句")return selfdef __exit__(self, exc_type, exc_val, exc_tb):print("退出 `with` 语句")if exc_type:print(f"发生异常:{exc_val}")return True  # 处理异常,不抛出with MyContext():print("执行 `with` 代码块")1 / 0  # ❌ 发生异常
print("代码继续执行")

输出:

进入 `with` 语句
执行 `with` 代码块
退出 `with` 语句
发生异常:division by zero
代码继续执行

分析:

  • 1 / 0 触发异常,with 立刻结束,调用 __exit__() 处理。
  • __exit__() 返回 True,异常被处理,不会向上传播。

3️⃣ 总结

with 语句的结束时机:

  1. 正常执行完代码块(执行完最后一行)。
  2. 遇到异常with 立刻结束,并调用 __exit__() 释放资源。
  3. 遇到 returnbreakcontinuewith 立刻结束,资源被释放。

💡 简单记住with 一旦代码块结束或发生异常,就立刻释放资源,自动退出! 🚀

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

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

相关文章

浏览器的Cookie 过期时间存储

Cookie 是服务器发送到浏览器的小型文本数据,用于跟踪用户状态(如登录信息、偏好设置),存储大小通常限制为 4KB,每个域名下最多允许约 20-50 个 Cookie(不同浏览器不同)。 属性 属性说明示例注…

hive全量迁移脚本

#!/bin/bash #场景:数据在同一库下,并且hive是内部表(前缀的hdfs地址是相同的)#1.读取一个文件,获取表名#echo "时间$dt_jian_2-------------------------" >> /home/hadoop/qianyi_zengliang/rs.txt#…

进阶——第十六届蓝桥杯嵌入式熟练度练习(开发板捕获频率和占空比)

单通道捕获频率 HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1); void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {if(htim->InstanceTIM2) {cap1HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);TIM2-&…

Python中如何进行数据库连接?

在 Python 中进行数据库连接,不同的数据库需要使用不同的库。下面分别介绍几种常见数据库(SQLite、MySQL、PostgreSQL)的连接方法。 1. 连接 SQLite 数据库 SQLite 是一种轻量级的嵌入式数据库,Python 标准库中自带了sqlite3模块…

用C语言实现通用排序函数:深入理解指针与函数指针的魅力

在C语言的学习与应用中&#xff0c;排序是一个非常基础且重要的算法。今天&#xff0c;我们就来深入探讨如何使用C语言实现一个通用的排序函数&#xff0c;通过这个过程&#xff0c;我们将对指针和函数指针有更深刻的理解。 #define _CRT_SECURE_NO_WARNINGS #include<std…

Deepseek R1模型本地化部署与API实战指南:释放企业级AI生产力

摘要 本文深入解析Deepseek R1开源大模型的本地化部署流程与API集成方案&#xff0c;涵盖从硬件选型、Docker环境搭建到模型微调及RESTful接口封装的完整企业级解决方案。通过电商评论分析和智能客服搭建等案例&#xff0c;展示如何将前沿AI技术转化为实际生产力。教程支持Lin…

使用verilog 实现 cordic 算法 ----- 旋转模式

1-设计流程 ● 了解cordic 算法原理&#xff0c;公式&#xff0c;模式&#xff0c;伸缩因子&#xff0c;旋转方向等&#xff0c;推荐以下链接视频了解 cordic 算法。哔哩哔哩-cordic算法原理讲解 ● 用matlab 或者 c 实现一遍算法 ● 在FPGA中用 verilog 实现&#xff0c;注意…

Python常见面试题的详解7

1. 内置的数据结构有哪几种 Python 中有多种内置的数据结构&#xff0c;主要分为以下几种&#xff1a; 1.1 数值类型 整数&#xff08;int&#xff09;&#xff1a;用于表示整数&#xff0c;没有大小限制。例如&#xff1a;1, -5, 100。浮点数&#xff08;float&#xff09;…

什么叫以太网?它与因特网有何区别?

以太网和互联网的定义与区别 以太网&#xff08;Ethernet&#xff09;和互联网&#xff08;Internet&#xff09;是两个不同的概念&#xff0c;虽然它们密切相关&#xff0c;但它们的作用和定义是不同的。 以太网&#xff08;Ethernet&#xff09; 以太网是一个 局域网&…

教育小程序+AI出题:如何通过自然语言处理技术提升题目质量

随着教育科技的飞速发展&#xff0c;教育小程序已经成为学生与教师之间互动的重要平台之一。与此同时&#xff0c;人工智能&#xff08;AI&#xff09;和自然语言处理&#xff08;NLP&#xff09;技术的应用正在不断推动教育内容的智能化。特别是在AI出题系统中&#xff0c;如何…

VScode内接入deepseek包过程(本地部署版包会)

目录 1. 首先得有vscode软件 2. 在我们的电脑本地已经部署了ollama&#xff0c;我将以qwen作为实验例子 3. 在vscode上的扩展商店下载continue 4. 下载完成后&#xff0c;依次点击添加模型 5. 在这里可以添加&#xff0c;各种各样的模型&#xff0c;选择我们的ollama 6. 选…

docker安装mysql:8.0

1.docker源 目前docker国内的源基本上用不了了&#xff0c;建议去淘宝找一找&#xff0c;我整了一个大概是10R一个月。 2.拉取镜像 docker pull mysql:8.0 3.启动容器 命令如下&#xff1a; docker run \-p 3306:3306 \-e MYSQL_ROOT_PASSWORD123456 \-v /home/data/mysq…

作用域链精讲

作用域链精讲 1编译阶段1.1分词1.2解析(解析为抽象语法树AST)1.3代码生成 2执行阶段3查询阶段4嵌套机制(这个比较重要)----就近原则5异常5.1计算机为啥要区分LHS和RHS5.2RHS查询5.3LHS查询 6什么是词法作用域7遮蔽效应8变量和函数的声明提升&#xff08;也是预解析&#xff09;…

4.【线性代数】——矩阵的LU分解

四 矩阵的LU分解 1. AB的逆矩阵2. 转置矩阵3. ALU3.1 2x2矩阵3.2 3x3矩阵3.3 nxn的矩阵分解的次数&#xff1f; 1. AB的逆矩阵 { ( A B ) ( B − 1 A − 1 ) I ( B − 1 A − 1 ) ( A B ) I ⇒ ( A B ) − 1 B − 1 A − 1 \begin{cases} (AB)(B^{-1}A^{-1}) I\\ (B^{-1}A^…

Arduino-ESP8266 GPIO(中断或轮询)

检测GPIO高低电平 1. 中断 2. 轮询 gpio.ino // GPIO按键输入 // 监听高电平接线图 // ESP8266 NodeMCU // ┌───────────┐ // │ D1(GPIO5) │──────┤按键一端 // │ │ │ // │ 3V3 │──────┤按键另一端 // └───…

FPGA简介|结构、组成和应用

Field Programmable Gate Arrays&#xff08;FPGA&#xff0c;现场可编程逻辑门阵列&#xff09;&#xff0c;是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物&#xff0c; 是作为专用集成电路&#xff08;ASIC&#xff09;领域中的一种半定制电路而出现的&#xff0c…

iOS 获取设备占用内存

获取应用占用内存 获取应用进程占用内存 - (NSUInteger)memoryUsage {task_vm_info_data_t vmInfo;mach_msg_type_number_t count TASK_VM_INFO_COUNT;kern_return_t result task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&vmInfo, &count);if (result …

WPF的MVVMLight框架

在NuGet中引入该库&#xff1a; MVVMLight框架中的命令模式的使用&#xff1a; <StackPanel><TextBox Text"{Binding Name}"/><TextBox Text"{Binding Title}"/><Button Content"点我" Command"{Binding ShowCommand…

如何使用OPENAI的Whisper功能进行音频字母提取功能

首先你可以使用 Python 中的 requests 库来下载该音频文件&#xff0c;然后通过 open() 打开该文件并传递给 OpenAI Whisper API。 完整代码如下&#xff1a; 安装需要的库&#xff1a; pip install openai requests Python 代码&#xff1a; OPENAI_API_KEY "your o…

地平线征程6全球首发上车比亚迪,开启大规模量产交付

2月10日&#xff0c;比亚迪举办智能化战略发布会&#xff0c;对外正式公布全民智驾战略&#xff0c;并发布全新天神之眼高阶智驾系统。未来&#xff0c;比亚迪全系车型将搭载天神之眼高阶智驾系统。 值得注意的是&#xff0c;地平线最新一代车载智能计算方案征程6系列全球首发…