Python Contextlib

Fariba Laiq 2023年1月30日
  1. 在 Python 中使用 with 语句作为上下文管理器
  2. 在 Python 中使用函数装饰器@contextmanager
Python Contextlib

有时,我们会使用一些资源,例如文件。当我们完成它的工作时,我们打开它并忘记关闭它。

这是一种不好的编码习惯,当打开太多文件时会产生问题。即使我们不再需要这些资源,该程序也可能无限期地获取它们。

这种情况会导致内存泄漏。为了自动处理这些事情,Python 有上下文管理器。

他们负责管理资源。contextlib 是一个 Python 库,它使用 with 关键字提供资源管理实用程序。

在 Python 中使用 with 语句作为上下文管理器

在 Python 中,with 语句管理资源并处理异常。所以它作为一个上下文管理器工作。

当代码到达 with 语句时,它会临时分配资源。当 with 语句块完成其执行时,先前获取的资源将被释放。

在下面的代码中,我们创建并打开了一个文件。当控件脱离 with 块时,with 块中获取的资源将被释放。

示例代码:

with open("file.txt", "w+") as f:
    print("File Opened")

输出:

File Opened

我们也可以在我们的程序中包含上下文管理器功能。为此,我们的类必须有方法 __enter__()__exit__()

为了理解上下文管理器的流程,我们使用 print 语句执行了以下代码,该语句在控制转移到相应块时运行。

示例代码:

class MyContextManager:
    def __init__(self):
        print("In init method")

    def __enter__(self):
        print("In enter method")

    def __exit__(self, exc_type, exc_value, exc_traceback):
        print("In exit method")


with MyContextManager() as m:
    print("With block")

输出:

In init method
In enter method
With block
In exit method

在 Python 中使用函数装饰器@contextmanager

另一种将函数作为上下文管理器的方法是使用函数装饰器@contextmanager。装饰器是一个函数,它接受另一个函数作为输入,扩展它的功能/修改它的行为,并返回另一个函数作为输出。

使用这个装饰器时,我们不必编写单独的类或 __enter__()__exit__() 函数。我们必须从 contextlib 模块导入上下文管理器。

我们将在函数上方使用@contextmanageryield 关键字类似于用于返回值/控制的 return 语句。

yield 关键字之前的所有内容都将被视为 __enter__ 部分,而 yield 之后的所有内容将被视为 __exit__ 部分。

示例代码:

from contextlib import contextmanager


@contextmanager
def MyContextManager():
    print("In enter method")
    yield
    print("In exit method")


with MyContextManager() as m:
    print("With block")

输出:

In enter method
With block
In exit method
作者: Fariba Laiq
Fariba Laiq avatar Fariba Laiq avatar

I am Fariba Laiq from Pakistan. An android app developer, technical content writer, and coding instructor. Writing has always been one of my passions. I love to learn, implement and convey my knowledge to others.

LinkedIn