Python 上下文管理器

虽然 Python 的上下文管理器被广泛使用,但很少有人理解其背后的目的。这些语句通常用于读写文件,通过确保特定资源仅在特定进程中使用,来帮助应用程序节省系统内存并改进资源管理。

with 语句

上下文管理器是一个对象,它在上下文(一段代码块)开始和结束时会收到通知。你通常使用 with 语句来使用它。它负责处理通知。

例如,文件对象就是上下文管理器。当上下文结束时,文件对象会自动关闭:

# 上下文管理器:自动处理资源清理
# 退出 'with' 块时文件自动关闭
with open(filename) as f:  # 'f' 是文件对象
    file_contents = f.read()

# 即使发生错误,文件也会在此处自动关闭
测验

登录后即可答题并追踪学习进度

使用上下文管理器(with 语句)的主要好处是什么?
A. 自动处理资源清理,即使发生错误
B. 使代码执行速度更快
C. 允许多个文件同时打开
D. 阻止所有错误

任何导致代码块执行结束的操作都会导致调用上下文管理器的退出方法。这包括异常,当错误导致你过早地退出一个打开的文件或连接时,这会很有用。在没有正确关闭文件/连接的情况下退出脚本是个坏主意,可能会导致数据丢失或其他问题。通过使用上下文管理器,你可以确保始终采取预防措施以防止以这种方式造成损害或损失。

编写你自己的上下文管理器

也可以使用生成器语法来编写上下文管理器,这要归功于 contextlib.contextmanager 装饰器:

# 使用 contextlib 装饰器的基于函数的上下文管理器
import contextlib
@contextlib.contextmanager
def context_manager(num):
    print('Enter')  # yield 之前的代码在 __enter__ 上运行
    yield num + 1   # yield 的值成为 'cm' 变量
    print('Exit')    # yield 之后代码在 __exit__ 上运行

with context_manager(2) as cm:  # cm 接收 yield 的值 (3)
    print('Right in the middle with cm = {}'.format(cm))
Enter
Right in the middle with cm = 3
Exit

基于类的上下文管理器

你可以定义基于类的上下文管理器。关键方法是 __enter____exit__

# 基于类的上下文管理器:实现 __enter__ 和 __exit__ 方法
class ContextManager:
    def __enter__(self, *args, **kwargs):  # 进入 'with' 块时调用
        print("--enter--")
        return self  # 可以返回对象用作 'as' 变量

    def __exit__(self, *args):  # 退出 'with' 块时调用
        print("--exit--")

with ContextManager():  # 调用 __enter__,完成后调用 __exit__
    print("test")
--enter--
test
--exit--
测验

登录后即可答题并追踪学习进度

一个类要用作上下文管理器,必须实现哪些方法?
A. **init****del**
B. **enter****exit**
C. openclose
D. startstop

相关链接