欢迎访问宙启技术站
智能推送

contextlib模块中的contextmanagers用法详解

发布时间:2023-12-28 03:50:44

contextlib 模块是 Python 标准库中的一个模块,用于创建上下文管理器。上下文管理器是一种可以在代码块执行前后进行一些特定操作的对象,常用于资源管理,如文件操作、网络连接等。contextlib 模块提供了一些用于创建上下文管理器的装饰器和辅助工具函数。

下面我们详细介绍 contextlib 模块中的几个常用装饰器和辅助函数以及它们的使用方法,并附带例子说明。

1. @contextmanager 装饰器

@contextmanager 是 contextlib 模块中最常用的装饰器,用于将一个生成器函数(包含 yield 语句)转换为上下文管理器。所装饰的生成器函数需要定义两个部分,一个是进入上下文前的代码,一个是从上下文退出后的代码。

使用步骤:

- 定义一个生成器函数,该函数需要包含至少一个 yield 语句。

- 使用 @contextmanager 装饰器装饰该生成器函数。

- 在生成器函数内部,yield 语句前的部分用于进入上下文前的代码,yield 语句后的部分用于从上下文退出后的代码。

示例:

from contextlib import contextmanager

@contextmanager
def file_open(file_name):
    file = open(file_name, 'w')                    # 进入上下文前的代码
    yield file                                     # 生成器函数的 yield 语句
    file.close()                                   # 从上下文退出后的代码

with file_open('test.txt') as f:
    f.write('Hello, World!')

在上面的例子中,我们定义了一个生成器函数 file_open,使用 @contextmanager 装饰该函数。通过 with 语句创建上下文,并在进入上下文前打开一个文件,然后使用 yield 语句生成该文件对象,最后在退出上下文后关闭文件。

2. closing 函数

closing 函数用于创建一个上下文管理器,用于包装一个没有实现上下文管理协议(__enter__ 和 __exit__ 方法)的对象,使其能够在 with 语句中使用。

使用步骤:

- 导入 closing 函数。

- 使用 with 语句创建上下文,传入一个需要包装的对象。

示例:

from contextlib import closing
from urllib.request import urlopen

with closing(urlopen('http://www.example.com')) as response:
    for line in response:
        print(line)

在上面的例子中,我们使用 closing 函数创建一个上下文管理器,使得 urlopen 函数返回的 response 对象能够在 with 语句中使用。在进入上下文前,urlopen 函数会打开一个 URL,然后通过 with 语句遍历 response,打印出 URL 的内容。

3. suppress 函数

suppress 函数用于创建一个上下文管理器,用于过滤掉指定的异常,不让它们引发错误。

使用步骤:

- 导入 suppress 函数。

- 使用 with 语句创建上下文,传入需要过滤的异常。

示例:

from contextlib import suppress
import os

with suppress(FileNotFoundError):
    os.remove('file_not_exist.txt')

在上面的例子中,我们使用 suppress 函数创建一个上下文管理器,使得 os.remove 函数在删除一个不存在的文件时不会引发 FileNotFoundError 异常。在进入上下文后,os.remove 函数会尝试删除一个不存在的文件,但是由于我们在上下文中过滤掉了 FileNotFoundError 异常,所以不会产生错误。

总结:

contextlib 模块提供了一些用于创建上下文管理器的装饰器和辅助函数,方便我们处理资源管理等操作。我们可以使用 @contextmanager 装饰器将一个生成器函数转换为上下文管理器,使用 closing 函数包装一个对象以便在 with 语句中使用,使用 suppress 函数过滤掉指定的异常。以上就是 contextlib 模块的用法以及对应的示例。