我正在为我正在进行的项目提供多个上下文管理器。它即将发货,我遇到了一些我开始恐慌的事情。
我的印象是你不应该再加上作为上下文管理器类的__exit__方法的参数传递的异常。但是,我正在进行一些测试,看起来上下文管理器正在抑制一个被抛入其中的异常。当我将__exit__方法更改为如下所示:
def __exit__(self, type_, value, trace):
if trace is not None:
print('ERROR IN TRACEBACK: ' + str(value))
# PYTHON 2.7 RAISE SYNTAX:
raise type_, value, trace
这些错误似乎正确地通过了。
我的问题是:如果type_,value和trace不是None,那么在__exit__方法中处理异常的正确方法是什么?提升(重新加注?)这样的例外是不是很糟糕? 这是我应该怎么做的?
我遇到的错误可能是由其他原因造成的。通常我会仔细检查这一切,但我的时间似乎非常有限。我希望有人可以解释这个函数的正确实现和
最终: 我可以在上下文管理器__exit__方法中安全地保留raise type_,value,trace吗?
答案 0 :(得分:7)
__exit__
方法的返回值应该指示是否应该重新引发传递给它的异常(the docs)
<强>
contextmanager.__exit__(exc_type, exc_val, exc_tb)
强>退出运行时上下文并返回一个指示是否存在的布尔标志 发生的异常应该被抑制。如果发生异常 在执行with语句的主体时,参数包含 异常类型,值和回溯信息。否则,全部 三个参数都是无。
因此,只要您的__exit__
方法返回False
- y,就会在没有明确执行任何操作的情况下重新引发异常。
此外,docs explicilty状态不自行重新提出异常:
传递的异常不应该明确重新加载 - 相反, 此方法应返回false值以指示该方法 成功完成,不想压制凸起 例外。这允许上下文管理代码(例如 contextlib.nested)轻松检测是否
__exit__()
方法实际上已经失败了。