Python 上下文管理器:使用块创建自定义
了解如何用 Python 编写自定义上下文管理器。掌握 contextmanager 装饰器和 __enter__/__exit__ 方法以确保资源安全。
概述
上下文管理器是 Python 中的一种优雅机制,旨在处理外部资源的设置和拆卸。在软件中,许多操作需要成对的操作:打开和关闭文件、连接和断开与数据库的连接,或者获取和释放锁。如果程序在设置步骤之后但在拆卸步骤之前崩溃,这些资源将保持锁定在内存中。上下文管理器保证在所有情况下都能安全地清理资源。
调用上下文管理器的标准方法是使用“with”语句。在底层,“with”语句中使用的任何对象都必须实现上下文管理器协议。该协议由两个特殊方法组成:`__enter__()`和`__exit__()`。当“with”块开始时,调用“__enter__()”来准备资源。当“with”块完成或引发异常时,会自动触发“__exit__()”,接收有关任何引发的异常的信息,以便它可以处理清理或抑制错误。
对于简单的用例,使用“__enter__”和“__exit__”方法编写类可能会感觉很冗长。为了简化这一点,Python 的标准库提供了“contextlib”模块,该模块具有“@contextmanager”装饰器。这个装饰器允许您编写一个包含单个“yield”语句的简单生成器函数。 “yield”之前的代码充当设置,产生的值充当资源,“yield”之后的代码代表清理。掌握上下文管理器可确保您的应用程序保持无泄漏。
代码和执行输出
实现 __enter__ 和 __exit__ 的自定义类来管理执行日志记录边界。
class CustomManager:
def __enter__(self):
print("--> Resource Setup: Entering the block")
return "RESOURCE_KEY"
def __exit__(self, exc_type, exc_value, traceback):
print("<-- Resource Teardown: Exiting the block")
if exc_type:
print(f"Exception Intercepted: {exc_value}")
return True # Suppress exceptions
with CustomManager() as res:
print(f"Working inside block with resource: {res}")
# Force an error to verify exception handling
x = 1 / 0
print("Program continues running safely.")--> Resource Setup: Entering the block
Working inside block with resource: RESOURCE_KEY
<-- Resource Teardown: Exiting the block
Exception Intercepted: division by zero
Program continues running safely.逐步实施
- 管理数据库事务(成功时提交,错误时回滚)
- 多线程代码中获取和释放线程锁
- 在单元测试脚本期间重定向标准输出 (stdout)
常见问题解答
如何抑制自定义上下文管理器中的异常?
通过从 __exit__ 方法返回 True。如果它返回 True,则块内引发的任何异常都将被抑制。
您可以在一个语句中组合多个上下文管理器吗?
是的,您可以用逗号分隔它们,例如, open('file1.txt') as f1, open('file2.txt') as f2:。
相关主题
推荐的 Python 资源
通过相关的交互式教程、备忘单和代码比较来扩展您的知识。