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

相关推荐
wljt几秒前
Linux 常用命令速查手册(Java开发版)
java·linux·python
WPG大大通4 分钟前
AIoT | 软件:Astra MCP边缘算力构建详解
经验分享·笔记·python·硬件架构·代码
国服第二切图仔14 分钟前
Rust开发实战之简单游戏开发(piston游戏引擎)
开发语言·rust·游戏引擎
ii_best21 分钟前
安卓/IOS工具开发基础教程:按键精灵一个简单的文字识别游戏验证
android·开发语言·游戏·ios·编辑器
波诺波22 分钟前
环境管理器
linux·前端·python
草莓熊Lotso25 分钟前
C++ 继承特殊场景解析:友元、静态成员与菱形继承的底层逻辑
服务器·开发语言·c++·人工智能·经验分享·笔记·1024程序员节
诸葛思颖25 分钟前
把本地 Python 项目用 Git 进行版本控制并推送到 GitHub
git·python·github
诗句藏于尽头27 分钟前
电脑使用软件控制本机屏和外接屏失效问题及解决
开发语言
测试老哥30 分钟前
自动化测试用例的编写和管理
自动化测试·软件测试·python·功能测试·测试工具·职场和发展·测试用例
不是株35 分钟前
JavaWeb(后端进阶)
java·开发语言·后端