Python with 语法详解

with 语句是 Python 中用于资源管理的语法糖,核心作用是自动管理资源的创建与释放(如文件、网络连接、锁等),避免因异常或逻辑错误导致资源泄漏。

1. 基本语法结构
with 上下文管理器 as 变量:
    # 执行代码块
    ...
  • 上下文管理器:实现了 __enter__()__exit__() 方法的对象(如文件对象、contextlib 中的工具类)。
  • __enter__():进入 with 代码块时执行,返回的对象会被赋值给 as 后的变量。
  • __exit__():离开 with 代码块时执行(无论是否发生异常),用于释放资源。
2. 典型应用场景:文件操作
# 传统方式(需手动关闭文件)
f = open("example.txt", "r")
try:
    content = f.read()
finally:
    f.close()

# with 简化后
with open("example.txt", "r") as f:
    content = f.read()
  • 优势:无需手动调用 f.close(),即使代码块中发生异常,文件也会被自动关闭。
3. 自定义上下文管理器

通过实现 __enter____exit__ 方法,可创建自定义的上下文管理器:

class MyContext:
    def __enter__(self):
        print("进入上下文")
        return "资源对象"  # 赋值给 as 后的变量
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("离开上下文,释放资源")
        # 处理异常(若返回 True,异常会被压制;返回 False 则向外抛出)
        return False

with MyContext() as res:
    print(f"使用资源:{res}")

执行结果:

进入上下文
使用资源:资源对象
离开上下文,释放资源
4. contextlib 模块的便捷工具

Python 标准库 contextlib 提供了更灵活的上下文管理工具:

  • @contextmanager 装饰器:通过生成器简化上下文管理器的创建:

    from contextlib import contextmanager
    
    @contextmanager
    def my_context():
        print("进入")
        yield "资源"  # 相当于 __enter__ 的返回值
        print("退出")
    
    with my_context() as res:
        print(f"使用{res}")
    
  • closing:将不支持 with 的对象转换为上下文管理器:

    from contextlib import closing
    from urllib.request import urlopen
    
    with closing(urlopen("https://www.python.org")) as page:
        content = page.read()
    
5. 处理多资源管理

可同时管理多个资源,用逗号分隔即可:

with open("file1.txt", "r") as f1, open("file2.txt", "w") as f2:
    f2.write(f1.read())
6. 异常处理

with 代码块中发生异常时,__exit__ 会接收异常信息(exc_type, exc_val, exc_tb),可在其中决定是否捕获异常:

class ErrorHandlingContext:
    def __enter__(self):
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type:
            print(f"捕获异常:{exc_val}")
        return True  # 压制异常,不向外抛出

with ErrorHandlingContext():
    raise ValueError("测试异常")

执行后仅打印“捕获异常:测试异常”,不会终止程序。

with 语法的核心价值是简化资源管理逻辑,保证资源的可靠释放,是 Python 中编写健壮代码的重要工具。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐