【问题标题】:Use of "except Exception" vs. "except ... raise" in Python在 Python 中使用“except Exception”与“except ... raise”
【发布时间】:2017-03-09 21:52:45
【问题描述】:

我正在阅读一些包含类似于以下功能的源代码:

def dummy_function():
    try:
        g = 1/0
    except Exception as e:
        raise Exception("There is an error: {}".format(e))

据我了解,所有异常都派生自 Exception 类,因此这应该会捕获所有错误。那么,跟随https://docs.python.org/3/tutorial/errors.html,这不就等于

def dummy_function():
    try:
        g = 1/0
    except:
        print "There is an error:"
        raise

我注意到在这两种情况下打印输出的排列方式略有不同,但在我看来,第二种方法基本相同且不那么冗长。还是我错过了什么?

【问题讨论】:

  • 不,它们不等价。新的Exception 实例附加了不同的消息。这就是重新加注的全部意义,以改变信息。
  • 一条毯子 except: 捕获 BaseException 并且它也是子类,而 except Exception: 没有。

标签: python exception


【解决方案1】:

不,您的代码不等效,原因如下:

  • 空白except: 捕获所有 异常,包括从BaseException 派生的异常(SystemExitKeyboardInterruptGeneratorExit);捕获Exception 过滤掉那些您通常希望避免捕获而不加注的异常。在较旧的 Python 版本中,它还会捕获字符串异常(不再允许)。
  • except Exception as e 捕获子类,然后引发一个新的Exception() 实例;下游try...except语句中不能再使用特定类型信息。
  • 在 Python 3 中,从异常处理程序引发新异常会创建一个异常链(原始异常作为Exception.__context__ 属性添加,请参阅Python "raise from" usage
  • 消息已更新;这可能就是这里的重点,就是给异常一个不同的信息。

您找到的代码是.. 相当糟糕的做法。顶级异常处理程序应该只捕获并打印一条消息,也许还有一个回溯,而不是使用新消息重新引发异常(在 Python 2 中丢失有关原始异常的所有信息,在 Python 3 中使其无法访问异常在后面的处理程序中匹配)。

【讨论】:

  • 同样引发一个新的异常会创建一个异常链,而裸露的raise不会
  • @vaultah:只要这是 Python 3。
猜你喜欢
  • 2011-07-04
  • 2013-09-29
  • 2019-06-26
  • 2015-10-24
  • 1970-01-01
  • 2015-02-15
  • 1970-01-01
  • 2018-03-19
  • 2018-01-23
相关资源
最近更新 更多