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

相关推荐
开开心心就好10 分钟前
文档格式转换软件 一键Word转PDF
开发语言·前端·数据库·pdf·c#·word
从零开始学习人工智能10 分钟前
PDFMathTranslate:让科学PDF翻译不再难——技术原理与实践指南
java·开发语言·pdf
深盾科技15 分钟前
探索Swift Package Manager:全面指南
开发语言·ios·swift
拾忆,想起1 小时前
Redis发布订阅:实时消息系统的极简解决方案
java·开发语言·数据库·redis·后端·缓存·性能优化
qq_12498707531 小时前
基于改进蜂群优化算法的高频金融波动率预测系统 (源码+论文+部署+安装)
python·算法·金融·毕业设计·蜂群优化算法
AllyLi02242 小时前
CondaError: Run ‘conda init‘ before ‘conda activate‘
linux·开发语言·笔记·python
测试老哥2 小时前
如何用Postman做接口测试?
自动化测试·软件测试·python·测试工具·测试用例·接口测试·postman
羑悻的小杀马特2 小时前
【C++高并发内存池篇】ThreadCache 极速引擎:C++ 高并发内存池的纳秒级无锁革命!
开发语言·c++·多线程·高性能内存池
zhangbaolin2 小时前
open webui源码分析11-四个特征之记忆
python·大模型·memory·open webui
布朗克1682 小时前
OpenTelemetry 在 Spring Boot 项目中的3种集成方式
java·开发语言·opentelemetry