如何在Python中创建可跳过代码体的上下文管理器?
Python上下文管理器跳过代码体的实现方法
你提到的在代码体里加if ctx.proceed判断是最直观、可读性最好的方案,日常开发里优先推荐这种,因为一眼就能看出来代码体可能被跳过。但也有其他方式可以实现无需在代码体中写判断,直接跳过代码体进入__exit__阶段:
方法一:自定义类上下文管理器(通过异常控制)
通过在__enter__阶段抛出特定异常,再在__exit__中捕获并抑制异常,这样代码体就会被直接跳过:
class SkipBlockError(Exception): pass class Context: def __init__(self, skip): self.skip = skip def __enter__(self): if self.skip: # 抛出异常触发直接进入__exit__ raise SkipBlockError() return self def __exit__(self, exc_type, exc_val, exc_tb): # 捕获自定义异常,阻止其传播 if exc_type is SkipBlockError: print("执行__exit__逻辑,代码体已跳过") return True # 处理正常流程的清理或异常 print("执行__exit__逻辑,正常流程") return False # 测试跳过场景 with Context(skip=True): print("这段代码永远不会执行") # 测试正常执行场景 with Context(skip=False): print("这段代码会正常执行")
方法二:用contextlib生成器实现上下文管理器
利用contextlib.contextmanager装饰器,通过是否执行yield来控制代码体是否运行——不执行yield时,代码体直接被跳过,后续代码会作为__exit__逻辑执行:
from contextlib import contextmanager @contextmanager def skipable_context(skip): try: if not skip: yield # 只有不跳过的时候才进入代码体 # 不管是否跳过,都会执行这里的清理逻辑 print("执行上下文清理操作") finally: # 也可以在这里加额外的收尾逻辑 pass # 测试跳过场景 with skipable_context(skip=True): print("这段代码不会被执行") # 测试正常执行场景 with skipable_context(skip=False): print("这段代码会正常执行")
需要注意的是,第二种方法如果需要在正常场景返回上下文对象,要在yield后跟上返回值,比如yield self,否则跳过场景下无法获取上下文实例。
内容的提问来源于stack exchange,提问作者anom907 zat
相关产品推荐
相关产品推荐

