2010-09-03 61 views
3

我在Python中遇到了一个非常奇怪的行为,这种行为并不一致。为什么我在Python上得到不一致的异常?

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

通常这会得到我的消息,如:

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

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

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

这是很奇怪的,因为在所有情况下的例外来自同一蟒蛇方法,codecs.open(...)

什么让我不知道更多关于此的是,如果我删除处理异常将达到与上水平正确的文本(完整的错误信息),永远!

except IOError as msg: 
    print(msg) 
    raise msg 

上例将总是打印一个完整的消息,如IOError: [Errno 13] Permission denied: u'filename'

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

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

我怀疑这跟sys.exit()的用法有关,因为print(msg)会给出好的结果,但是sys.exit不会。

回答

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

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

我想象有这样的代码:

error = (13, 'Permision denied') 

#more code 

raise error 

他们改成了异常某人后只是做:

raise IOError(error) 
0

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

所以你可能想从msg.args元组构造出你自己的字符串,并用它作为你想要显示的“消息”。

相关问题