我最近在 Python 的 with 语句中遇到了一个奇怪的行为。我有一个代码,它使用 Python 的上下文管理器来回滚__exit__
方法中的配置更改。经理return False
在 finally 块中有一个值__exit__
。我已经在以下代码中隔离了这种情况 - 唯一的区别是 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
. 异常不会在 with-statement in 之外抛出,Manager1
以及为什么它会在 exit in 中抛出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。