简体   繁体   English

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

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

I have several context managers for a project I'm working on. 我正在为一个正在研究的项目提供几个上下文管理器。 It is about to ship and I've run into something I'm starting to panic about. 它即将发货,我遇到了一些我开始恐慌的事情。

I was under the impression that you should not reraise the exceptions passed as arguments to the __exit__ method of the context manager class. 我的印象是你不应该再加上作为上下文管理器类的__exit__方法的参数传递的异常。 However, I was preforming some testing and it seemed like a context manager was suppressing an exception that was being thrown inside it. 但是,我正在进行一些测试,看起来上下文管理器正在抑制一个被抛入其中的异常。 When I changed my __exit__ methods to look like this: 当我将__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

the errors seemed to pass through correctly. 这些错误似乎正确地通过了。

My question is: What is the correct way to deal with exceptions in the __exit__ method if type_, value, and trace are not None? 我的问题是:如果type_,value和trace不是None,那么在__exit__方法中处理异常的正确方法是什么? Is it bad to raise (reraise?) the exception like this? 提升(重新加注?)这样的例外是不是很糟糕? Is this how I'm supposed to do it? 这是我应该怎么做的?

The error I encountered might have been caused by something else. 我遇到的错误可能是由其他原因造成的。 Normally I would go through and test this all thoroughly, but my time seems to be very limited at the moment. 通常我会仔细检查这一切,但我的时间似乎非常有限。 I'm hoping somebody can explain the proper implementation of this function and 我希望有人可以解释这个功能的正确实现

Ultimately: Can I safely leave the raise type_, value, trace in my context manager __exit__ methods? 最终:我可以在上下文管理器__exit__方法中安全地保留raise type_,value,trace吗?

The __exit__ method's return value should indicate whether or any exception that was passed to it should be re-raised (per the docs ): __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. 如果在执行with语句的主体时发生异常,则参数包含异常类型,值和回溯信息。 Otherwise, all three arguments are None. 否则,所有三个参数都是None。

So as long as your __exit__ method is returning something False -y, the exception should get re-raised without you explicitly doing anything. 因此,只要您的__exit__方法返回False -y,就应该重新引发异常而不显式执行任何操作。

Furthermore, the docs explicilty state not to re-raise the exception yourself: 此外,docs explicilty声明不要自己重新提出异常:

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. 传入的异常永远不应该显式重新标记 - 相反,此方法应返回false值以指示方法已成功完成且不希望抑制引发的异常。 This allows context management code (such as contextlib.nested) to easily detect whether or not an __exit__() method has actually failed. 这允许上下文管理代码(例如contextlib.nested)轻松检测__exit__()方法是否实际上已失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM