在Python2.7上下文管理器类中处理异常的正确方法

时间:2014-07-10 21:09:43

标签: python exception-handling contextmanager

我正在为我正在进行的项目提供多个上下文管理器。它即将发货,我遇到了一些我开始恐慌的事情。

我的印象是你不应该再加上作为上下文管理器类的__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吗?

1 个答案:

答案 0 :(得分:7)

__exit__方法的返回值应该指示是否应该重新引发传递给它的异常(the docs

  

<强> contextmanager.__exit__(exc_type, exc_val, exc_tb)

     

退出运行时上下文并返回一个指示是否存在的布尔标志   发生的异常应该被抑制。如果发生异常   在执行with语句的主体时,参数包含   异常类型,值和回溯信息。否则,全部   三个参数都是无。

因此,只要您的__exit__方法返回False - y,就会在没有明确执行任何操作的情况下重新引发异常。

此外,docs explicilty状态自行重新提出异常:

  

传递的异常不应该明确重新加载 - 相反,   此方法应返回false值以指示该方法   成功完成,不想压制凸起   例外。这允许上下文管理代码(例如   contextlib.nested)轻松检测是否__exit__()   方法实际上已经失败了。