我想捕获上下文管理器内部引发的异常。我创建了一个简单的示例来重现该问题。
所以,我的上下文管理器:
class Test(object):
def div(self, a, b):
return a // b
def __enter__(self):
print('enter')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit')
return self
以及我想在其中使用的类:
class Container(object):
def test_exc(self, a, b):
try:
with Test() as test:
try:
result = test.div(a, b)
print(a, '/', b, '=', result)
return result
except Exception as e:
raise e
except Exception as e:
print(e)
用法:
c = Container()
c.test_exc(5, 1)
c.test_exc(5, 0)
输出:
enter
5 / 1 = 5
exit
enter
exit
因此,当引发异常时(在上面的示例中为ZeroDivisionError
),父try ... catch不会捕获该异常。如何解决这个问题?
我认为上下文管理器可以有选择地传递他们捕获的异常。
要停止异常,__exit__
方法应返回True
(并且self
可能计为True
)
要传递异常,请返回False
:
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit')
return False
错误是您的__exit__()
函数的实现。
文档说明:
从此方法返回真实值将导致with语句抑制异常并继续执行以下语句在with语句之后。否则例外该方法执行完后,继续传播。执行此方法期间发生的异常将替换任何with语句的主体中发生的异常。
只需移除
return self
来自exit函数