【python】python进阶——with关键字

目录

引言

[一、with 关键字的作用](#一、with 关键字的作用)

二、工作原理

三、内置的上下文管理器

1、文件操作

2、线程锁

3、数据库连接

四、自定义上下文管理器

[1. 通过类实现](#1. 通过类实现)

[2. 使用 contextlib 模块](#2. 使用 contextlib 模块)

[五、异常处理与 with 语句](#五、异常处理与 with 语句)

六、异步上下文管理器

七、实际应用场景

总结


引言

在 Python 编程中,with 关键字是一个强大且常用的工具,它通过上下文管理器(Context Manager)简化了资源管理,让代码更加清晰、可读,同时避免了资源泄漏和异常处理问题。本文将详细探讨**with** 关键字的工作原理、使用方法以及如何自定义上下文管理器。


一、with 关键字的作用

在文件操作、数据库连接或网络请求等场景中,我们经常需要打开资源并在使用后正确关闭。传统的做法是使用 try...finally 块来确保资源被释放:

python 复制代码
file = open('example.txt', 'r')
try:
    content = file.read()
finally:
    file.close()

这种方式虽然有效,但代码冗余且容易遗漏。with 关键字通过自动管理资源的分配和释放,让代码更简洁:

python 复制代码
with open('example.txt', 'r') as file:
    content = file.read()
# 文件会在 with 块结束后自动关闭

二、工作原理

with 语句通过上下文管理器协议(Context Manager Protocol)工作。任何实现了 **__enter__()__exit__()**方法的对象都可以作为上下文管理器。

  • __enter__() : 在进入 **with**块时调用,返回需要管理的资源。
  • __exit__(): 在退出 with 块时调用,负责清理工作(如关闭文件、释放锁等),并处理可能发生的异常。

执行流程:

python 复制代码
with ContextManager() as resource:
    # 执行操作

#等价于:
manager = ContextManager()
resource = manager.__enter__()
try:
    # 执行操作
finally:
    manager.__exit__()

三、内置的上下文管理器

Python 标准库中的许多模块提供了内置的上下文管理器:

1、文件操作

python 复制代码
with open('file.txt', 'w') as f:
    f.write('Hello, World!')

2、线程锁

python 复制代码
import threading

lock = threading.Lock()
with lock:
    # 临界区代码

3、数据库连接

python 复制代码
import sqlite3

with sqlite3.connect('database.db') as conn:
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM table')

四、自定义上下文管理器

1. 通过类实现

自定义一个上下文管理器需要实现 __enter__ 和**__exit__**方法:

python 复制代码
class CustomContextManager:
    def __enter__(self):
        print("进入上下文")
        return self  # 返回管理的资源

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("退出上下文")
        if exc_type:
            print(f"异常类型: {exc_type}, 异常值: {exc_val}")
        return False  # 若返回 True,则抑制异常

2. 使用 contextlib 模块

Python 的 contextlib 模块提供了更简洁的方式来创建上下文管理器,尤其是使用 **@contextmanager**装饰器:

python 复制代码
from contextlib import contextmanager

@contextmanager
def custom_context():
    print("进入上下文")
    try:
        yield "资源"  # 生成资源
    finally:
        print("退出上下文")

# 使用示例
with custom_context() as resource:
    print(f"正在使用 {resource}")

五、异常处理与 with 语句

**__exit__**方法接收三个参数来处理异常:

  • exc_type: 异常类型。

  • exc_val: 异常值。

  • exc_tb: 异常追踪信息。

__exit__ 返回 True,则异常会被抑制,否则异常会继续传播。


六、异步上下文管理器

Python 3.5+ 支持异步上下文管理器,通过 **async with__aenter____aexit__**方法实现:

python 复制代码
class AsyncContextManager:
    async def __aenter__(self):
        print("异步进入上下文")
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        print("异步退出上下文")

# 使用示例
async def main():
    async with AsyncContextManager() as acm:
        print("异步操作")

七、实际应用场景

  1. 资源管理:自动关闭文件、释放锁或数据库连接。

  2. 临时操作:例如临时修改环境变量后恢复。

  3. 事务管理:数据库事务的提交或回滚。

  4. 计时器:测量代码块的执行时间。

python 复制代码
from time import time
from contextlib import contextmanager

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

with timer():
    # 执行耗时操作
    sum(range(1000000))

总结

  • with 关键字通过上下文管理器自动管理资源,避免资源泄漏。

  • 内置的上下文管理器(如文件操作、线程锁)可直接使用。

  • 可以通过类或 contextlib 模块自定义上下文管理器。

  • 异常处理和异步操作也得到良好支持。

掌握 with 关键字能让你的代码更加简洁、安全和高效,是 Python 编程中不可或缺的工具。

相关推荐
databook5 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar6 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户8356290780516 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_6 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机13 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机14 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机14 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机14 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i14 小时前
drf初步梳理
python·django
每日AI新事件14 小时前
python的异步函数
python