如何在Python中使用上下文管理器(with语句)
了解上下文管理器在 Python 中的工作原理。掌握with语句,管理系统资源,并编写自定义上下文管理器。
概述
正确管理外部资源(例如关闭文件句柄、断开数据库连接和释放线程锁)对于构建可靠的生产就绪软件至关重要。未能释放资源可能会导致内存泄漏、文件锁定错误和应用程序挂起。
Python 的“with”语句通过创建上下文管理器来简化资源清理。上下文管理器保证当控制离开块时自动执行清理操作,即使代码抛出异常或提前退出。这消除了对冗长、重复的“try-finally”块的需要。
虽然上下文管理器最常与“open()”等内置操作相关联,但您可以轻松设计自己的自定义上下文管理器。您可以通过创建一个实现“__enter__”和“__exit__”魔术方法的类来构建它们,或者编写一个用“contextlib.contextmanager”装饰器装饰的生成器函数。
代码和执行输出
该脚本演示了使用类实现和 contextlib 装饰器在 Python 中编写自定义上下文管理器。
context_managers.py
在编辑器中尝试from contextlib import contextmanager
# Method 1: Class-based context manager
class CustomResource:
def __enter__(self):
print("[Resource] Opening connection...")
return self
def do_work(self):
print("[Resource] Performing action...")
def __exit__(self, exc_type, exc_val, exc_tb):
print("[Resource] Closing connection safely.")
return False
print("--- Class Context Manager ---")
with CustomResource() as resource:
resource.do_work()
# Method 2: Generator-based context manager (contextlib)
@contextmanager
def simple_timer():
print("\n[Timer] Started...")
try:
yield
finally:
print("[Timer] Finished!")
print("\n--- Decorator Context Manager ---")
with simple_timer():
print("Performing tasks inside context...")端子输出
--- Class Context Manager ---
[Resource] Opening connection...
[Resource] Performing action...
[Resource] Closing connection safely.
--- Decorator Context Manager ---
[Timer] Started...
Performing tasks inside context...
[Timer] Finished!逐步实施
- 打开文件、数据库或锁时使用with语句来保证资源安全。
- 使用带有 __enter__ 和 __exit__ 魔术方法的类定义自定义上下文管理器。
- 在生成器函数上使用 @contextlib.contextmanager 装饰器作为更简单的基于函数的替代方案。
- 将资源关闭操作放置在清理块内,以确保即使发生错误它们也能运行。
常见问题解答
__exit__ 方法接收哪些参数?
__exit__ 方法接收三个参数,表示异常详细信息(如果引发):exc_type(异常类型)、exc_val(异常值)和 exc_tb(回溯)。如果没有发生错误,则所有三个都将作为 None 传递。
上下文管理器可以抑制异常吗?
是的。如果 __exit__ 方法返回真值(如 True),Python 会抑制异常并在 with 块之后继续执行。如果返回 False,则正常引发异常。
相关主题
推荐的 Python 资源
通过相关的交互式教程、备忘单和代码比较来扩展您的知识。