Python笔记之上下文管理器
一、简介
本章节详细讲解Python中的上下文管理器,包括自定义上下文管理器和with
语句的深度理解。上下文管理器提供了一种简洁的方式来管理资源的获取与释放,尤其在文件操作、数据库连接等场景中得到广泛应用。
二、上下文管理器基础
1、概念说明
- 上下文管理器 是一种对象,定义了
__enter__
和__exit__
方法,用于管理资源的获取与释放。 with
语句用于简化上下文管理器的使用,它会在执行with
语句块之前自动调用__enter__
方法,并在执行结束后自动调用__exit__
方法,无论执行过程中是否发生异常。
with
语句的基本结构
with 上下文管理器 as 变量:
# 执行代码块
三、内置上下文管理器:文件操作
1、概念说明
- Python的文件操作使用内置的上下文管理器来简化文件的打开与关闭,确保文件在使用完毕后正确地关闭,即使在执行过程中发生异常也能确保资源的释放。
2、代码示例
(1) 使用with
语句进行文件操作
# 使用with语句自动管理文件打开与关闭
with open("example.txt", "w") as file:
file.write("Hello, Python!")
运行结果
- 该代码会在执行完文件写入操作后,自动关闭文件,确保资源的正确释放。
(2) 使用with
语句读取文件
# 使用with语句读取文件内容
with open("example.txt", "r") as file:
content = file.read()
print(content)
运行结果
Hello, Python!
四、自定义上下文管理器
1、概念说明
- 自定义上下文管理器通过实现
__enter__
和__exit__
方法来定义资源的获取与释放行为。 __enter__
方法用于在with
语句块开始时进行资源的初始化。__exit__
方法用于在with
语句块结束时释放资源。
2、代码示例
(1) 自定义上下文管理器类
class MyContextManager:
def __enter__(self):
print("资源已获取")
return self # 返回一个可以在with语句中使用的对象
def __exit__(self, exc_type, exc_value, traceback):
print("资源已释放")
# 如果发生异常,返回True则阻止异常传播,返回False则允许异常传播
if exc_type:
print(f"发生异常:{exc_value}")
return True # 阻止异常传播
# 使用自定义上下文管理器
with MyContextManager() as manager:
print("执行with语句内部代码")
# 下面的代码会抛出异常,进入__exit__方法
raise ValueError("自定义异常")
运行结果
资源已获取
执行with语句内部代码
资源已释放
发生异常:自定义异常
(2) 自定义上下文管理器使用contextlib
模块
- Python的
contextlib
模块提供了简化上下文管理器定义的工具。通过contextlib.contextmanager
装饰器,可以将生成器函数转换为上下文管理器。
from contextlib import contextmanager
@contextmanager
def my_context_manager():
print("资源已获取")
yield # 使用yield关键字表示with语句的执行部分
print("资源已释放")
# 使用自定义上下文管理器
with my_context_manager():
print("执行with语句内部代码")
运行结果
资源已获取
执行with语句内部代码
资源已释放
五、with
语句的深度理解
1、概念说明
with
语句的核心作用是确保上下文管理器对象的资源能够在不管程序是否发生异常的情况下正确释放。with
语句通过调用上下文管理器的__enter__
和__exit__
方法来实现这一点。
(1) __enter__
方法
- 当
with
语句开始时,__enter__
方法会被调用,通常用于资源的初始化,并且该方法的返回值会赋给as
后面的变量。
(2) __exit__
方法
- 当
with
语句结束时,__exit__
方法会被调用,用于释放资源。 __exit__
方法的四个参数分别是:异常类型、异常值、异常追踪信息和None
(如果没有异常发生)。
2、代码示例
(1) 捕获异常并在__exit__
中处理
class SafeDivision:
def __enter__(self):
print("开始计算")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("计算结束")
if exc_type:
print(f"捕获异常:{exc_value}")
return True # 返回True表示异常已被处理,程序不会抛出异常
with SafeDivision() as div:
result = 10 / 0 # 会抛出异常,但会被__exit__方法处理
运行结果
开始计算
计算结束
捕获异常:division by zero
六、小结
本章节详细讲解了Python中的上下文管理器,包括内置的文件操作上下文管理器和自定义上下文管理器。通过with
语句的使用,可以简化资源的管理,确保在程序结束时自动释放资源,避免资源泄漏。自定义上下文管理器提供了灵活的方式来管理复杂的资源,contextlib
模块的装饰器也进一步简化了这一过程。