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

The correct way to handle Exceptions in a Python2.7 context manager class

我在一个项目中有几个上下文管理器。它就要装船了,我碰到了一些我开始担心的事情。

我的印象是,您不应该重新评估作为参数传递给上下文管理器类的_uuexit_uuu方法的异常。然而,我正在执行一些测试,看起来上下文管理器正在抑制一个被抛出的异常。当我把退出方法改成如下:

1
2
3
4
5
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

错误似乎正确地通过了。

我的问题是:如果类型、值和跟踪不是"无",那么在退出方法中处理异常的正确方法是什么?提升(重新提升)是否不好?像这样的例外?我应该这样做吗?

我遇到的错误可能是由其他原因引起的。通常情况下,我会彻底地测试这一切,但目前我的时间似乎非常有限。我希望有人能解释这个函数的正确实现,以及

归根结底:我能在上下文管理器退出方法中安全地保留提升类型_uuuuuuuuuu、值、跟踪吗?


__exit__方法的返回值应指明是否应(根据文档)重新引发或重新引发传递给它的任何异常:

contextmanager.__exit__(exc_type, exc_val, exc_tb)

Exit the runtime context and return a Boolean flag indicating if any
exception that occurred should be suppressed. If an exception occurred
while executing the body of the with statement, the arguments contain
the exception type, value and traceback information. Otherwise, all
three arguments are None.

只要您的__exit__方法返回了Falsey的内容,那么应该在不显式执行任何操作的情况下重新引发异常。

此外,docs明确声明不要自己重新引发异常:

The exception passed in should never be reraised explicitly - instead,
this method should return a false value to indicate that the method
completed successfully and does not want to suppress the raised
exception. This allows context management code (such as
contextlib.nested) to easily detect whether or not an __exit__()
method has actually failed.