当我收到异常作为cPickle.UnpicklingError: invalid load key, 'ÿ'.
并尝试打印它时,当我尝试将其插入我的(unicode)错误消息时,它会引发Unicode解码错误:
try:
settings = _load()
except cPickle.UnpicklingError, err:
msg = _(u"Error reading ... (the error is: '%s')")
cont = askYes(msg % err, _(u"Settings Load Error")) # raises
尝试了msg % unicode(err.message, encoding='utf-8')
中的解决方法,但显然err.message
不是有效的 unicode 字符串("UnicodeDecodeError:'utf8' 编解码器无法解码位置 19 中的字节0xff:无效的起始字节")
那么处理这个问题的最python的方法是什么?我应该将"忽略"或"替换"传递给unicode()
吗?
编辑:askYes(None, msg % repr(err), _(u"Settings Load Error"))
给出类似的东西:
(the error is: 'UnpicklingError("invalid load key, 'xff'.",)'). # ff is ÿ
不吹,但仍然...
编辑2:我报告的错误与人为的错误有点混淆:
u'%s' % "cPickle.UnpicklingError: invalid load key, 'ÿ'."
Traceback (most recent call last):
File "<input>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 44: ordinal
not in range(128)
这是来自 pycharm 内部的解释器 - 显然ÿ
在那里'xc3xbf'
(...
确保可以在错误消息中看到结果的一种方法是使用 repr
,或者更直接地%r
而不是%s
:永远不会失败(因为任何对象都有表示形式,并且所有表示形式都在 ASCII 中,包括可能的转义序列),并且还显示(作为转义序列)否则可能不可见的字符。
repr
(以及旧式格式字符串中的'%r'
)委托给对象类型的__repr__
特殊方法;每个对象类型都负责知道如何在明确(不一定是超级可读)的 ASCII 字符串中最好地表示自身。 字符串和字节序列特别擅长这一点,因此repr
非常适合它们。
OP 已经这样做了,但不喜欢结果的美学(在err.message
repr
与err
repr
之间变化)。 不幸的是,美学是repr
最不优先考虑的:相反,它都是关于完整、明确的信息。
另一个想法是使用永不失败的编码(解码每个字节,尽管可能解码为无意义的上下文字形)进行解码,例如"iso-8859-1"。 但我相信,这并没有比repr
真正的进步;美学的改进是值得商榷的,并且在"完整,明确的信息"方面存在损失的可能性。
只是为了澄清几点:
Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit (Intel)] on win32
>>> u'%s' % "cPickle.UnpicklingError: invalid load key, 'ÿ'."
Traceback (most recent call last):
File "<input>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 44: ordinal not in range(128)
这是因为 python 2 有助于尝试解码字符串以将其插入 unicode 字符串 - 默认编码为 ASCII - 当然 ascii 无法解码'ÿ'
(解码意味着将字节转换为代码点) - 因此例外。下面的工作是因为它不会尝试在 ascii 中解码任何内容 - 只显示字节:
>>> '%s' % "cPickle.UnpicklingError: invalid load key, 'ÿ'."
"cPickle.UnpicklingError: invalid load key, 'xc3xbf'."
下面也可以工作,并且(如控制台在 ascii 中显示的)显示 unicode 字节值(即将 unicode 字符串 - 其中的字节 - 编码为 ascii 字符):
>>> u'%s' % u"cPickle.UnpicklingError: invalid load key, 'ÿ'."
u"cPickle.UnpicklingError: invalid load key, 'xff'."
与以下逻辑相同:
>>> u'á, é, í, ó, ú, ü, ñ'
u'xe1, xe9, xed, xf3, xfa, xfc, xf1'
>>> 'á, é, í, ó, ú, ü, ñ'
'xc3xa1, xc3xa9, xc3xad, xc3xb3, xc3xba, xc3xbc, xc3xb1'
正是这种内部编码/解码让我感到困惑 - 并且仍然让我有点困惑。