Python,UnicodeDecodeError试图打印包含非ascii字符的异常
当我得到一个异常,如Python,UnicodeDecodeError试图打印包含非ascii字符的异常,python,python-2.7,unicode,encoding,utf-8,Python,Python 2.7,Unicode,Encoding,Utf 8,当我得到一个异常,如cPickle.UnpicklingError:加载键“ÿ”无效。并且我尝试打印它时,当我尝试将其插入我的(unicode)错误消息时,它会引发unicode解码错误: try: settings = _load() except cPickle.UnpicklingError, err: msg = _(u"Error reading ... (the error is: '%s')") cont = askYes(msg % err, _(u"Se
cPickle.UnpicklingError:加载键“ÿ”无效。
并且我尝试打印它时,当我尝试将其插入我的(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:无效的起始字节”)
那么,什么是处理这一问题的最有说服力的方法呢?我应该将“忽略”或“替换”传递给unicode()
编辑:askYes(无,消息%repr(错误),u(设置加载错误))
给出如下信息:
(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)
u“%s%”cPickle.UnpicklingError:无效的加载键“ÿ”
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
UnicodeDecodeError:“ascii”编解码器无法解码位置44:ordinal中的字节0xc3\
不在范围内(128)
这是pycharm内部的解释器提供的-显然
ÿ
是'\xc3\xbf'
那里(…)确保您可以在错误消息中看到结果的一种方法是使用repr
,或者更直接地使用%r
,而不是%s
:永远不会失败(因为任何对象都有一个表示,并且所有表示都是ASCII格式,可能包括转义序列),并且还显示(作为转义序列)可能不可见的字符
repr
(以及旧式格式字符串中的'%r'
)委托给对象类型的\uuuuu repr\uuuuu
特殊方法;每个对象类型负责知道如何以明确(不一定是超级可读)的方式最好地表示自己ASCII字符串。字符串和字节序列尤其擅长于此,因此repr
非常适合它们
OP已经做到了这一点,但不喜欢结果的美观(在repr
的err.message
与repr
的err
之间有所不同)。不幸的是,美观是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)
下面的代码也可以使用,并且(控制台以ascii显示)显示unicode字节值(即将unicode字符串(其中的字节)编码为ascii字符):
与中的逻辑相同:
>>> u'á, é, í, ó, ú, ü, ñ'
u'\xe1, \xe9, \xed, \xf3, \xfa, \xfc, \xf1'
>>> 'á, é, í, ó, ú, ü, ñ'
'\xc3\xa1, \xc3\xa9, \xc3\xad, \xc3\xb3, \xc3\xba, \xc3\xbc, \xc3\xb1'
正是这种内部编码/解码让我感到困惑,现在仍然有点困惑。使用
repr
,或者更直接地使用%r
,而不是%s
,是显示可疑内容字符串的最佳方式——它可能表示Unicode,也可能不表示Unicode,但您显示的\x0f
或0xff
您前面提到过,请仔细考虑一下编码。如果err.message
是一个随机的字节集合,没有任何押韵或原因,您怎么可能比通过repr
更好地显示它呢?!忽略
或替换
会隐藏潜在的宝贵信息,以用于调试目的--永远不要这样做一条错误消息!@AlexMartelli:谢谢-是的,我不会使用replace和co-我只是想吓唬别人,所以他们回答我:D.你能详细说明一下repr的用法吗?使用repr(err.message)会更好吗?我很感谢你的完整回答answer@AlexMartelli:repr(错误消息):(错误为:“\x0f”“无效的加载密钥”。”
while repr(err):(错误是:“UnpicklingError”(“无效的加载键,“\x0f.”)”)
。我宁愿在“(错误是:UnpicklingError:“无效的加载键,“\x0f.””)这行中有一些东西-我必须手动构造它吗?我也承认为什么repr()
成功解码了字符串。字符串中似乎没有任何Unicode问题,如图所示:'\x0f'
没有此类问题,而'\xff'
会。尝试将err.message解码为“iso-8859-1”,这不会失败(它会解码每个字节,尽管可能是无意义的符号)顺便说一句,repr
没有问题也就不足为奇了--repr
从来不会失败--'\xff'
和'\x0f'
之间的炼金术变形让我感到困惑!@AlexMartelli:哦,很抱歉-我可能已经变形了错误消息-显然err.message
是无效加载键,'+chr(0xff)
位于“UnicodeDecodeError:'utf8'编解码器…位置19”。为什么repr从未失败?它使用iso-8859-1吗?
>>> 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'