如何以显式调用__enter__()和__exit__()方法替代Python with语句?
显式调用
__enter__()和__exit__()替代with语句的正确写法 with语句是Python的语法糖,它的核心执行逻辑是:
- 获取上下文管理器对象(比如
open("test.txt", "w")的返回值) - 调用管理器的
__enter__()方法,返回值对应as后的变量 - 执行代码块逻辑
- 无论代码块是否抛出异常,都会调用管理器的
__exit__(exc_type, exc_val, exc_tb)方法,异常时传入对应信息,无异常则三个参数均为None - 若
__exit__()返回True,异常会被压制;否则异常继续传播
针对你给出的with代码示例,正确的显式调用写法如下:
import sys # 获取上下文管理器对象 file_manager = open("test.txt", "w") try: # 调用__enter__获取目标对象(open的__enter__返回自身) file = file_manager.__enter__() file.write("Hello, World!") except BaseException: # 捕获异常时,获取标准异常信息 exc_type, exc_val, exc_tb = sys.exc_info() # 调用__exit__,若返回False则重新抛出异常 if not file_manager.__exit__(exc_type, exc_val, exc_tb): raise else: # 无异常时,传入None调用__exit__ file_manager.__exit__(None, None, None)
原错误代码的问题
- 错误直接调用
file.__exit__():通用场景下__enter__可能返回其他对象,必须用原始上下文管理器调用__exit__(open场景下两者是同一对象,但写法不具备通用性) - 异常信息获取方式错误:应使用
sys.exc_info()获取exc_type, exc_val, exc_tb - 未处理
__exit__()返回值的作用:该返回值决定是否压制异常 - 结构逻辑错误:未确保
__exit__在任何情况下都被正确调用
内容的提问来源于stack exchange,提问作者Toothpick Anemone
相关产品推荐
相关产品推荐

