【问题标题】:The correct way to handle Exceptions in a Python2.7 context manager class在 Python2.7 上下文管理器类中处理异常的正确方法
【发布时间】:2014-09-01 09:44:46
【问题描述】:

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

我的印象是您不应该重新引发作为参数传递给上下文管理器类的 __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__ 方法中处理异常的正确方法是什么?提出(重新提出?)这样的异常是不是很糟糕? 这是我应该做的吗?

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

最终: 我可以安全地将 raise type_, value, trace 留在我的上下文管理器 __exit__ 方法中吗?

【问题讨论】:

    标签: python exception-handling contextmanager


    【解决方案1】:

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

    contextmanager.__exit__(exc_type, exc_val, exc_tb)

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

    只要您的__exit__ 方法返回False-y 的内容,就应该在您不明确执行任何操作的情况下重新引发异常。

    此外,文档明确声明 自己重新引发异常:

    传入的异常不应该被显式地重新引发 - 相反, 此方法应返回一个 false 值以指示该方法 成功完成并且不想压制提出的 例外。这允许上下文管理代码(例如 contextlib.nested) 来轻松检测__exit__() 方法实际上失败了。

    【讨论】:

    • 我认为 None 是一个 False-y 值......现在我正在查看代码,我意识到我正在返回对象本身的东西。 (如果没有记错,应该由 _enter_ 方法返回)。
    猜你喜欢
    • 2016-05-30
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 2015-03-25
    相关资源
    最近更新 更多