【问题标题】:Why doesn't it work to append information in the exception message?为什么在异常消息中附加信息不起作用?
【发布时间】:2014-12-16 19:05:47
【问题描述】:

为什么这不起作用?

try:
    1/0
except ZeroDivisionError as e:
    e.message += ', you fool!'
    raise

不使用修改后的消息,即使它保留在异常实例上。以上是否有工作模式?行为应该类似于我当前的以下解决方法:

try:
    1/0
except ZeroDivisionError as e:
    args = e.args
    if not args:
        arg0 = ''
    else:
        arg0 = args[0]
    arg0 += ', you fool!'
    e.args = (arg0,) + args[1:]
    raise

我知道 exception chaining 在 python3 中,它看起来不错,但不幸的是在 python2 中不起作用。那么在 python2 中重新引发异常的常用方法是什么?

注意:由于here 提到的警告和注意事项,我不想挖掘回溯并创建新异常,而是重新引发现有异常 实例。

【问题讨论】:

    标签: python exception


    【解决方案1】:

    更改e.args 是执行此操作的唯一方法。 implementation for BaseException.__str__ 只考虑 args 元组,根本不考虑 message

    static PyObject * 
    BaseException_str(PyBaseExceptionObject *self)
    {
        PyObject *out;
    
        switch (PyTuple_GET_SIZE(self->args)) { 
        case 0:
            out = PyString_FromString("");
            break;
        case 1:
            out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
            break;
        default:
            out = PyObject_Str(self->args);
            break;
        } 
    
        return out;
    }
    

    这应该不会太出人意料,因为BaseException.message is deprecated 自 Python 2.6 以来。

    【讨论】:

      【解决方案2】:

      我认为没有比您的解决方法更好的解决方案了。 ZeroDivisionError 不使用 message 属性来构建其输出,因此修改它不会有任何效果。

      如果您专门捕获 ZeroDivisionError 它应该始终只有一个参数,因此以下更简洁的版本将起作用:

      try:
          1/0
      except ZeroDivisionError as e:
          e.args = (e.args[0] + ', you fool!',)
          raise
      

      如果你检查 ZeroDivisionError 的属性,它只有argsmessage 并且它不使用message 这么短的创建一个新错误,修改 args 几乎是唯一可能的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-18
        • 1970-01-01
        • 1970-01-01
        • 2014-06-12
        • 1970-01-01
        • 1970-01-01
        • 2017-07-03
        • 1970-01-01
        相关资源
        最近更新 更多