为什么我在Python上得到不一致的异常?

时间:2010-09-03 18:42:34

标签: python exception-handling ioerror

我在Python中遇到了一种非常奇怪的行为,这种行为并不一致。

...
except IOError as msg:
    sys.exit("###ERROR IOError: %s" % (msg))

通常这会给我一个消息:

###ERROR IOError: [Errno 13] Permission denied: 'filename'

在相同的情况下,上面的代码给了我tuple而不是正确的错误消息。

###ERROR IOError: (13, 'Permission denied')

这很奇怪,因为在所有情况下异常都来自同一个python方法,codecs.open(...)

让我更加想知道的是,如果我删除处理,异常将使用正确的文本(完整错误消息)到达上层,总是!

except IOError as msg:
    print(msg)
    raise msg

以上示例将始终打印完整的消息,例如IOError: [Errno 13] Permission denied: u'filename'

为什么会发生这种情况,如何防止这种情况发生,我不想向用户提供不完整的错误消息。

我想在测试文件中重现此行为,但我无法在项目外重现此行为。

我怀疑这与sys.exit()的使用有关,因为print(msg)会产生良好的结果,但sys.exit没有。

3 个答案:

答案 0 :(得分:5)

首先,在重新提取异常时,从不执行except Exc as e: raise e总是只是普通raise,没有参数。这将保留回溯。

不,这与sys.exit无关,而是与实例化异常的方式有关。你 总是得到例外;有时它的字符串表示将类似于tuple

>>> print IOError(13, 'Permission denied')
[Errno 13] Permission denied
>>> print IOError((13, 'Permission denied'))
(13, 'Permission denied')

如果没有显示完整的回溯,就无法确定以这种方式引发错误的确切原因。而且,如果没有像我指出的那样适当地再加注,你将无法获得完整的回溯。

答案 1 :(得分:1)

在Python 1.5之前,异常是字符串。之后,他们将其更改为类以保持向后兼容性。现在你只能引发异常实例或类。

我想有一个像这样的代码:

error = (13, 'Permision denied')

#more code

raise error

在他们将其更改为异常后,有人刚刚做了:

raise IOError(error)

答案 2 :(得分:0)

我建议你不要依赖异常的字符串表示;你可以将它命名为msg,但它既不是字符串也不是消息;这是一个例外情况。

因此,您可能希望从msg.args元组构造自己的字符串,并将其用作要显示的“消息”。