【Python 内置模块】contextlib

2024-01-20 00:00:00

目录:

contextlib 模块介绍

contextlib 模块用于简化上下文管理器的创建和使用,让开发者能够更简洁、安全地管理资源(如文件、锁、数据库连接等),从而避免资源泄漏。

with 语句要求对象实现 __enter__()__exit__() 方法,构成上下文管理器协议。
contextlib 可以简化这些方法。

with open('example.txt', 'w') as file:
    file.write('Hello, World!')

@contextmanager

可以将一个包含 yield 语句的生成器函数直接转换为上下文管理器,无需定义类。

yield 语句之前的代码相当于 __enter__(),用于获取和设置资源;yield 语句返回的值会绑定到 as 子句的变量;yield 语句之后的代码(通常放在 finally 块中)相当于 __exit__(),用于确保资源释放。

示例: 文件操作

from contextlib import contextmanager

@contextmanager
def managed_file(filename, mode='r'):
    f = open(filename, mode)
    try:
        yield f  # 将打开的文件对象提供给 with 代码块使用
    finally:
        f.close()  # 无论 with 块中是否发生异常,文件都会被关闭

# 使用方式
with managed_file('data.txt') as file:
    data = file.read()
    print(data)

示例: 数据库连接

import sqlite3
from contextlib import contextmanager

@contextmanager
def get_db(db_path):
    conn = sqlite3.connect(db_path)
    try:
        yield conn  # 提供连接给 with 代码块
        conn.commit()  # 如果没有异常,提交事务
    except Exception:
        conn.rollback()  # 如果发生异常,回滚事务
        raise  # 重新引发异常,这是关键!否则 with 语句会认为异常已被处理[1](@ref)
    finally:
        conn.close()  # 最终确保连接关闭

with get_db('app.db') as conn:
    cursor = conn.cursor()
    cursor.execute("INSERT INTO logs (message) VALUES ('test entry')")

示例: 性能计时器。上下文管理器不限于“打开-关闭”,任何“进入时做A,离开时做B”的模式都适用

import time
from contextlib import contextmanager

@contextmanager
def timer(name):
    start = time.time()
    print(f"{name} 开始...")
    yield  # 这里不需要提供值给 as
    elapsed = time.time() - start
    print(f"{name} 完成,耗时 {elapsed:.2f} 秒")

with timer("数据清洗流程"):
    # 模拟耗时操作
    data = [i**2 for i in range(1000000)]

返回首页

本文总阅读量  次
皖ICP备17026209号-3
总访问量: 
总访客量: