【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 编程中不可或缺的工具。

相关推荐
zone773911 分钟前
001:简单 RAG 入门
后端·python·面试
F_Quant17 分钟前
🚀 Python打包踩坑指南:彻底解决 Nuitka --onefile 配置文件丢失与重启报错问题
python·操作系统
允许部分打工人先富起来1 小时前
在node项目中执行python脚本
前端·python·node.js
IVEN_1 小时前
Python OpenCV: RGB三色识别的最佳工程实践
python·opencv
haosend2 小时前
AI时代,传统网络运维人员的转型指南
python·数据网络·网络自动化
曲幽2 小时前
不止于JWT:用FastAPI的Depends实现细粒度权限控制
python·fastapi·web·jwt·rbac·permission·depends·abac
IVEN_20 小时前
只会Python皮毛?深入理解这几点,轻松进阶全栈开发
python·全栈
Ray Liang21 小时前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
AI攻城狮1 天前
如何给 AI Agent 做"断舍离":OpenClaw Session 自动清理实践
python
千寻girling1 天前
一份不可多得的 《 Python 》语言教程
人工智能·后端·python