Python如何通过上下文管理器在无as关键字时修改其他类行为
结论
这个需求完全可以实现,不需要依赖as关键字绑定上下文对象。核心实现逻辑是通过类级别的状态标记,在上下文进入时写入全局生效的附加值配置、退出时自动回滚配置,A类的加法方法运算时主动读取当前生效的上下文配置即可完成逻辑修改。
实现要点
- 为B类维护一个类级别的栈结构存储当前生效的附加值,使用栈结构是为了兼容嵌套上下文场景,保证多层上下文嵌套时,退出内层可以正确恢复外层的配置
- B的
__enter__方法执行时,将当前实例的added_amount压入栈,原有返回self的逻辑不影响功能,即使不用as接收也完全正常 - B的
__exit__方法执行时,弹出栈顶存储的当前附加值,完成状态回滚,保证上下文外的逻辑不受影响 - 修改A类的
__add__方法,计算基础和之后先检查B类的状态栈,如果栈非空说明当前在B的上下文块内,取栈顶的附加值追加到结果中,否则直接返回基础和
完整可运行代码
class A: def __init__(self, amount): self.amount = amount def __add__(self, other): base_sum = self.amount + other.amount # 检查当前是否处于B上下文生效状态 if B._active_stack: base_sum += B._active_stack[-1] return base_sum class B: # 类级别的栈,存储所有嵌套上下文中的生效附加值 _active_stack = [] def __init__(self, added_amount): self.added_amount = added_amount def __enter__(self): print('enter method called') # 进入上下文时将当前附加值压入栈 B._active_stack.append(self.added_amount) return self def __exit__(self, exc_type, exc_value, exc_traceback): print('exit method called') # 退出上下文时弹出栈顶值,恢复之前的状态 B._active_stack.pop() # 严格按照要求的形式调用,不使用as子句 with B(1000): a = A(1) + A(5) print(a) # 验证退出上下文后A的加法行为恢复默认 print(A(1) + A(5))
运行结果
enter method called 1006 exit method called 6
该实现同时支持多层B上下文嵌套使用:内层上下文会生效自己的附加值,退出内层后自动恢复外层的附加值配置,完全退出所有B上下文后A的加法逻辑回到原始状态。
内容的提问来源于stack exchange,提问作者Zaza Sichinava
相关产品推荐
相关产品推荐

