問題描述
為 KeyError 打印出奇怪的錯誤消息 (Strange error message printed out for KeyError)
為什麼在 Python 2.7 中
>>> test_string = "a \\test"
>>> raise ValueError("This is an example: %s" % repr(test_string))
ValueError: This is an example: 'this is a \\test'
但是
>>> raise KeyError("This is an example: %s" % repr(test_string))
KeyError: This is an example: 'this is a \\\\test'
(注意4個反斜杠)
參考解法
方法 1:
The __str__
methods for ValueError
and KeyError
differ:
>>> str(ValueError(repr('\\')))
"'\\\\'"
>>> str(KeyError(repr('\\')))
'"\'\\\\\\\\\'"'
or using print
:
>>> print str(ValueError(repr('\\')))
'\\'
>>> print str(KeyError(repr('\\')))
"'\\\\'"
That's because KeyError
shows the repr()
of the 'key' you passed in, so you can distinguish between a string and integer key:
>>> print str(KeyError(42))
42
>>> print str(KeyError('42'))
'42'
or more importantly, so you can still recognise an empty string key error:
>>> print str(KeyError(''))
''
The ValueError
exception doesn't have to deal with Python values, it's message is meant to be a string, always.
From the KeyError_str()
function in the CPython source code:
/* If args is a tuple of exactly one item, apply repr to args[0].
This is done so that e.g. the exception raised by {}[''] prints
KeyError: ''
rather than the confusing
KeyError
alone. The downside is that if KeyError is raised with an explanatory
string, that string will be displayed in quotes. Too bad.
If args is anything else, use the default BaseException__str__().
*/
ValueError
uses the default BaseException_str()
function, which for the one‑argument case just uses str(arg[0])
.
(by Petrarch、Martijn Pieters)