Python之with语句

文章目录

Python中的with语句详解

with语句是Python中用于资源管理的关键语句,它简化了异常处理中资源分配和释放的操作,特别是对于文件操作、数据库连接、线程锁等需要明确释放资源的场景。

一、基本语法

python 复制代码
with expression [as variable]:
    with-block

二、工作原理

with语句背后的工作机制依赖于上下文管理器协议 ,即实现了__enter__()和__exit__()方法的对象。

  1. 执行expression,获取上下文管理器对象
  2. 调用上下文管理器的__enter__()方法
  3. 如果有as variable,则将__enter__()的返回值赋给variable
  4. 执行with-block中的代码
  5. 无论是否发生异常,都会调用上下文管理器的__exit__()方法

三、文件操作中的with语句

1. 基本用法

python 复制代码
with open('example.txt', 'r') as file:
    content = file.read()
    # 不需要手动调用file.close()

2. 同时打开多个文件

python 复制代码
with open('input.txt', 'r') as infile, open('output.txt', 'w') as outfile:
    content = infile.read()
    outfile.write(content.upper())

四、with语句的优势

  1. 自动资源管理:确保文件等资源被正确关闭
  2. 异常安全 :即使在with块中发生异常,资源也会被正确释放
  3. 代码简洁 :减少了try-finally块的嵌套
  4. 可读性强:明确显示了资源的生命周期

五、自定义上下文管理器

1. 基于类的实现

python 复制代码
class MyContextManager:
    def __enter__(self):
        print("进入上下文")
        return self  # 可以返回其他对象
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("退出上下文")
        if exc_type:  # 如果有异常发生
            print(f"异常类型: {exc_type}")
            print(f"异常值: {exc_val}")
        # 返回True表示异常已被处理,False或None会向上传播异常
        return True

with MyContextManager() as cm:
    print("在上下文中")
    # 1/0  # 取消注释会触发异常

2. 使用contextlib模块

python 复制代码
from contextlib import contextmanager

@contextmanager
def my_context_manager():
    print("进入上下文")
    try:
        yield "资源对象"  # yield前的代码相当于__enter__
    finally:
        print("退出上下文")  # yield后的代码相当于__exit__

with my_context_manager() as resource:
    print(f"正在使用 {resource}")

六、常见应用场景

  1. 文件操作:自动关闭文件
  2. 数据库连接:自动提交/回滚事务并关闭连接
  3. 线程锁:自动获取和释放锁
  4. 临时修改:临时修改系统参数后恢复
  5. 计时操作:自动记录代码块执行时间
python 复制代码
# 计时器示例
import time
from contextlib import contextmanager

@contextmanager
def timer():
    start = time.time()
    try:
        yield
    finally:
        end = time.time()
        print(f"耗时: {end - start:.2f}秒")

with timer():
    # 需要计时的代码
    time.sleep(1)

七、注意事项

  1. with语句中的变量只在with块内有效
  2. 某些资源(如sys.stdin)不支持with语句
  3. 当需要长期保持资源打开时,不应使用with语句
  4. __exit__方法应该正确处理异常或返回True来抑制异常

with语句是Python中编写干净、安全代码的重要工具,合理使用可以显著提高代码的健壮性和可维护性。

相关推荐
默_笙5 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
qq_426003965 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫5 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
长沙三为智能科技5 天前
家政小程序开发从0到上线:五阶段交付流程与验收清单
python
伞伞悦读5 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
这个DBA有点耶5 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
DBA_G5 天前
从地面到云霄:GBase数据库在民航三大场景的落地实践
数据库
自由能燃气设备5 天前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南
大数据·数据库·人工智能
只睡四小时5 天前
Canvas 弹道联机实战:700 行 + 固定时间步长
python·websocket·html5·游戏开发·canvas
科创致远5 天前
科创致远 ESOP 系统核心效能与实战价值展示
大数据·数据库·人工智能·精益工程