Python中with语句直接调用构造函数时上下文内代码未执行问题
问题原因说明
你遇到的现象核心是__enter__方法缺少返回值,配合__exit__的异常吞吃逻辑,导致第一个with块内的代码执行时报错被静默处理,没有输出对应内容,具体细节如下:
- Python的
with ... as ...语法中,as后面的变量接收的是上下文管理器__enter__方法的返回值,而非上下文管理器实例本身。你当前的__enter__方法只有打印逻辑,没有显式写返回语句,默认返回None,因此第一个with块中的test变量实际是None。 - 第一个
with块执行print(f'in {test.name}')时,尝试访问None的name属性,会抛出AttributeError异常。 - 你定义的
__exit__方法返回了True,这个返回值的语义是「本次上下文执行遇到的异常已经处理完成,无需向外抛出」,因此异常被直接吞掉,print语句没执行完成就直接进入了__exit__的退出流程,自然看不到in first的输出。 - 第二个
with语句没有用as绑定新变量,使用的是外部提前定义好的test变量(就是Test('second')的实例对象),访问test.name不会报错,所以执行流程完全符合预期。
修复方案
给__enter__方法添加返回自身的逻辑即可:
def __enter__(self): print(f'entering {self.name}') return self
修改后执行代码就能得到你预期的输出。
内容的提问来源于stack exchange,提问作者Ian Newson
相关产品推荐
相关产品推荐

