ai agent(智能体)开发 python3基础9 with的体贴用法总结

在 Python 中,with 语句用于简化资源管理,确保资源的正确获取和释放(例如文件、网络连接、线程锁等)。它通过上下文管理器(Context Manager)实现,能自动处理异常和清理工作。以下是 with 语句的详细介绍:


一、基本用法

语法格式

with expression [as variable]:
    # 代码块

核心作用

  • 自动资源管理:在代码块执行前后,自动调用资源的初始化和清理方法。
  • 异常安全:即使代码块中发生异常,清理操作也会执行。

二、常见场景示例

1. 文件操作

手动管理文件

f = open('file.txt', 'r')
try:
    content = f.read()
finally:
    f.close()

使用 with

with open('file.txt', 'r') as f:
    content = f.read()
# 无需手动关闭文件,自动调用 f.close()

2. 线程锁管理
import threading

lock = threading.Lock()

with lock:
    # 临界区代码,锁会在代码块结束后自动释放
    print("Lock acquired")

3. 数据库连接

假设使用 sqlite3 模块:

import sqlite3

with sqlite3.connect('mydb.db') as conn:
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM users')
    data = cursor.fetchall()
# 自动提交事务并关闭连接

三、上下文管理器的工作原理

上下文管理器通过两个魔法方法实现:

  1. __enter__(): 进入代码块时调用,返回值会赋值给 as 后的变量。
  2. __exit__(exc_type, exc_val, exc_tb): 退出代码块时调用,处理异常和清理资源。

示例:自定义上下文管理器
class MyContextManager:
    def __enter__(self):
        print("Entering context")
        return self  # 返回的对象会被赋值给 as 后的变量
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Exiting context")
        # 如果返回 True,异常会被抑制;否则异常继续传播
        return False  

# 使用自定义上下文管理器
with MyContextManager() as cm:
    print("Inside the context")

输出

Entering context
Inside the context
Exiting context

四、使用 contextlib 简化实现

Python 的 contextlib 模块提供了装饰器和工具函数,快速创建上下文管理器。

1. 使用 @contextmanager 装饰器
from contextlib import contextmanager

@contextmanager
def my_context():
    print("Start")      # 相当于 __enter__()
    yield "Hello"      # yield 的值会赋值给 as 后的变量
    print("End")        # 相当于 __exit__()

with my_context() as msg:
    print(msg)          # 输出 "Hello"

输出

Start
Hello
End

2. 处理异常

在生成器中捕获异常:

@contextmanager
def error_handler():
    try:
        yield
    except Exception as e:
        print(f"Error occurred: {e}")
    finally:
        print("Cleanup")

with error_handler():
    1 / 0  # 触发异常

输出

Error occurred: division by zero
Cleanup

五、with 语句的底层流程

  1. 调用 expression__enter__() 方法。
  2. __enter__() 的返回值赋给 as 后的变量。
  3. 执行代码块。
  4. 无论是否发生异常,都调用 __exit__() 方法。
    • 如果发生异常,异常信息会传递给 __exit__()
    • __exit__() 返回 True,异常被抑制;否则继续传播。

六、适用场景总结

场景示例作用
文件操作with open(...) as f自动关闭文件
线程锁with threading.Lock()自动释放锁
数据库连接with sqlite3.connect(...)自动提交/回滚事务并关闭连接
临时资源分配自定义上下文管理器确保资源释放(如临时目录)
异常处理结合 try...except 使用集中处理异常和清理逻辑

七、注意事项

  1. 异常处理:如果 __exit__ 返回 True,异常会被抑制,否则异常会继续传播。
  2. 资源依赖:不要在 with 块外使用已释放的资源(如已关闭的文件)。
  3. 嵌套使用with 支持嵌套,按先进后出的顺序处理。

八、完整代码示例

# 自定义上下文管理器:计时器
import time

class Timer:
    def __enter__(self):
        self.start = time.time()
        return self
    
    def __exit__(self, *args):
        self.end = time.time()
        print(f"Time elapsed: {self.end - self.start:.2f} seconds")

with Timer():
    time.sleep(1.5)  # 模拟耗时操作

输出

Time elapsed: 1.50 seconds

通过 with 语句,Python 将资源管理代码与业务逻辑分离,使代码更简洁、安全且易维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一刀到底211

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值