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中编写干净、安全代码的重要工具,合理使用可以显著提高代码的健壮性和可维护性。

相关推荐
聆风吟º22 分钟前
【金仓数据库征文】Java 应用接入金仓数据库:从驱动、连接池到存储过程调试的踩坑实录
java·开发语言·数据库
森G38 分钟前
comfyui安装ComfyUI-Manager失败问题-解决办法
python
过期的秋刀鱼!40 分钟前
倾斜数据集的错误指标-混淆矩阵
人工智能·python·深度学习·机器学习·概率论·模型评估
能年玲奈喝榴莲牛奶1 小时前
使用AI编写-资产和漏洞管理系统
人工智能·python·网络安全·安全服务
程序员-Benothing2 小时前
MySQL 的覆盖索引是什么?
数据库·mysql
DeepVisionary2 小时前
再观察小星火:当大厂分成“冰封“,国产轻模式创作者平台如何跑出加速度
python·自动化
gb42152872 小时前
python中unstructured库和langchain-unstructured库在解析pdf文件的时候的区别?
python·langchain·pdf
vx-程序开发2 小时前
django医院预约挂号系统---附源码23353
java·javascript·spring boot·python·eclipse·django·php
数翊科技2 小时前
权威认可!HexaDB海纳分布式HTAP数据库通过CCRC EAL4增强级认证
数据库
星恒讯工业路由器3 小时前
MIMO与多天线技术:从5G到WiFi的工程解析
数据库·mysql·5g·工业物联网·mimo技术·天线隔离度·5g/wifi多天线