当我得到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:无效的起始字节”)
那么处理这个问题最灵活的方法是什么?我应该将'ignore'或'replace'传递给unicode()
吗?
编辑:askYes(None, msg % repr(err), _(u"Settings Load Error"))
提供类似的内容:
(the error is: 'UnpicklingError("invalid load key, '\xff'.",)'). # ff is ÿ
不吹,但仍然......
Edit2:我报告的错误与人为错误有点混淆:
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内部的解释器 - 显然ÿ
是'\xc3\xbf'
那里(...)
答案 0 :(得分:3)
确保您可以在错误消息中看到结果的一种方法是使用repr
或更直接%r
而不是%s
:永不失败(因为任何对象都有表示,并且所有表示都是ASCII,包括可能的转义序列),并且还显示(作为转义序列)可能不可见的字符。
repr
(以及旧式格式字符串中的'%r'
)委托给对象类型的__repr__
特殊方法;每个对象类型负责知道如何在一个明确的(不一定是超可读的)ASCII字符串中最好地表示自己。字符串和字节序列特别擅长,因此repr
非常适合它们。
OP已经这样做但不喜欢结果的美学(在repr
err.message
与repr
err
的{{1}}之间变化。不幸的是,美学是repr
的最重要的优先事项:相反,它完全是关于完整,明确的信息。
另一个想法是使用永不失败的编码进行解码(一个解码每个字节,但可能解码为无意义的上下文字形),例如&#39; iso-8859-1&#39;。但我认为,与repr
相比,它没有真正的改进;美学方面的改进是值得商榷的,并且有可能在完整,明确的信息方面造成损失。
答案 1 :(得分:0)
只是为了澄清一些观点:
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, '\xc3\xbf'."
下面也可以工作,并且(如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'
>>> 'á, é, í, ó, ú, ü, ñ'
'\xc3\xa1, \xc3\xa9, \xc3\xad, \xc3\xb3, \xc3\xba, \xc3\xbc, \xc3\xb1'
正是这种内部编码/解码使我感到困惑 - 并且仍然让我感到困惑。