Python3。如何在上下文管理器中正确引发异常以使用运算符处理异常?
Python3. How to correctly raise exception inside context manager to handle it out of with operator?
我想捕获在上下文管理器中引发的异常。我创建了简单的示例来重现该问题。
那么,我的上下文管理器:
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我想用的地方:
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__
方法应该 return True
(并且 self
可能算作 True
)
要传递异常,return False
:
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit')
return False
请参阅此 link PEP,其中一些伪代码显示了如何吞噬异常。
错误是你的 __exit__()
函数的实现。
文档指出:
returning a true value from this method will cause the with statement
to suppress the exception and continue execution with the statement
immediately following the with statement. Otherwise the exception
continues propagating after this method has finished executing.
Exceptions that occur during execution of this method will replace any
exception that occurred in the body of the with statement.
只需删除
return self
来自 __exit__()
函数。
没有 return 将 return None
计算为 False
我想捕获在上下文管理器中引发的异常。我创建了简单的示例来重现该问题。
那么,我的上下文管理器:
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我想用的地方:
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__
方法应该 return True
(并且 self
可能算作 True
)
要传递异常,return False
:
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit')
return False
请参阅此 link PEP,其中一些伪代码显示了如何吞噬异常。
错误是你的 __exit__()
函数的实现。
文档指出:
returning a true value from this method will cause the with statement to suppress the exception and continue execution with the statement immediately following the with statement. Otherwise the exception continues propagating after this method has finished executing. Exceptions that occur during execution of this method will replace any exception that occurred in the body of the with statement.
只需删除
return self
来自 __exit__()
函数。
没有 return 将 return None
计算为 False