3

我在 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不会。

4

3 回答 3

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')

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

于 2010-09-03T18:52:06.183 回答
1

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

我想有这样的代码:

error = (13, 'Permision denied')

#more code

raise error

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

raise IOError(error)
于 2010-09-03T19:55:19.393 回答
0

我建议您不要依赖异常的字符串表示形式;你可以命名它msg,但它既不是字符串也不是消息;这是一个异常实例。

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

于 2010-10-03T19:09:10.790 回答