【发布时间】:2014-08-24 11:52:33
【问题描述】:
我最近在 Python 的 with 语句中遇到了一个奇怪的行为。我有一个代码,它使用 Python 的上下文管理器来回滚 __exit__ 方法中的配置更改。经理在 __exit__ 的 finally 块中有一个 return False 值。我已经在下面的代码中隔离了这种情况 - 唯一的区别是 return 语句的缩进:
class Manager1(object):
def release(self):
pass # Implementation not important
def rollback(self):
# Rollback fails throwing an exception:
raise Exception("A failure")
def __enter__(self):
print "ENTER1"
def __exit__(self, exc_type, exc_val, exc_tb):
print "EXIT1"
try:
self.rollback()
finally:
self.release()
return False # The only difference here!
class Manager2(object):
def release(self):
pass # Implementation not important
def rollback(self):
# Rollback fails throwing an exception:
raise Exception("A failure")
def __enter__(self):
print "ENTER2"
def __exit__(self, exc_type, exc_val, exc_tb):
print "EXIT2"
try:
self.rollback()
finally:
self.release()
return False # The only difference here!
在上面的代码中,回滚失败并出现异常。我的问题是,为什么Manager1 的行为与Manager2 不同。异常不会在Manager1 中的 with 语句之外引发,以及为什么它会在Manager2 中退出时引发。
with Manager1() as m:
pass # The Exception is NOT thrown on exit here
with Manager2() as m:
pass # The Exception IS thrown on exit here
如果提供了异常,并且该方法希望抑制 异常(即,防止它被传播),它应该返回一个 真正的价值。否则,异常将正常处理 退出此方法。
在我看来,在这两种情况下 exit 都没有返回 True,因此在这两种情况下都不应该抑制异常。但是在 Manager1 中它是。谁能解释一下?
我使用 Python 2.7.6。
【问题讨论】:
标签: python with-statement contextmanager