【问题标题】:Detect whether an Exceptions was already handled in nested with statements in Python 2.7检测异常是否已经在 Python 2.7 中的嵌套语句中处理
【发布时间】:2014-07-07 16:42:48
【问题描述】:

考虑以下代码:

class Test(object):
    def __enter__(self):
        pass
    def __exit__(self,type,value,trace):
        if type:
            print "Error occured: " + str(value.args)
            #if I changed the next line to 'return True', the
            #'print "should not happen"' statements are executed, but the
            #error information would be only printed once (what I want)
            return False
        return True

with Test():
    with Test():
        with Test():
            raise Exception('Foo','Bar')
        print "should not happen"
    print "should not happen"

示例输出:

发生错误:('Foo', 'Bar')

发生错误:('Foo', 'Bar')

发生错误:('Foo', 'Bar')

我有几个嵌套的with 语句,并且想要处理代码中某处引发异常的情况。我想要实现的是停止执行(上例中没有“不应该发生”的输出),但错误信息只打印一次。因此,我需要以某种方式知道是否已经处理了相同的错误。

您知道如何实现这一目标吗?

【问题讨论】:

标签: python python-2.7 exception-handling with-statement contextmanager


【解决方案1】:

你不能真正干净地做到这一点——上下文管理器要么吞下异常,要么不吞下。

如果您对从管理器向外传播的异常感到满意(如果您在此处处理任意异常,则应该如此),您可以对异常实例进行猴子修补:

def __exit__(self, type, value, trace):
    if type:
        if not getattr(value, '_printed_it_already', False):
           print "error occured: " + str(value.args)
           value._printed_it_already = True
           return False
    return True

请注意,这种猴子修补在 Python 中是不受欢迎的……我认为值得问问你实际上在尝试做什么。通常当一个未处理的异常打印它的堆栈跟踪时,你会很清楚异常的args 是从什么开始的......

【讨论】:

  • 正是我想要的,谢谢!我知道这不是好习惯。我创建了一个小任务运行器,其中每个with 代表某种事务。 with 语法很容易使用,但我唯一的问题是输出错误(并且只执行一次)
【解决方案2】:

您可以将error_handled 属性添加到异常并对其进行测试:

class Test(object):
    def __enter__(self):
        pass
    def __exit__(self,type,value,trace):
        if type:
            if not getattr(value,'error_handled', False):
                value.error_handled = True
                print "Error occured: " + str(value.args)

with Test():
    with Test():
        with Test():
            raise Exception('Foo','Bar')
        print "should not happen"
    print "should not happen"

【讨论】:

    猜你喜欢
    • 2015-12-13
    • 1970-01-01
    • 2016-04-21
    • 2013-05-01
    • 2015-10-24
    • 2014-04-04
    • 2014-02-15
    • 1970-01-01
    • 2016-08-18
    相关资源
    最近更新 更多