Python,UnicodeDecodeError正在尝试打印包含非ascii字符的异常

2024-10-04 11:33:46 发布

您现在位置:Python中文网/ 问答频道 /正文

当我得到一个异常为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'codec无法解码位置19中的字节0xff:无效的起始字节”)

那么什么是最具Python式的处理方式呢?我应该将“ignore”或“replace”传递给unicode()?在

Edit:askYes(None, msg % repr(err), _(u"Settings Load Error"))给出了如下内容:

^{pr2}$

不吹但仍然。。。在

编辑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内部的解释器——显然ÿ在{}那里(…)


Tags: keyinsettings错误unicodeloadmsgerror
2条回答

为了澄清一些问题:

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)

这是因为Python2尝试对字符串进行解码以将其插入unicode字符串(默认编码为ASCII),当然ASCII无法解码'ÿ'(decode意味着将字节转换为码位),因此出现了异常。下面的工作原理是它不尝试解码任何东西-只显示字节-以ascii格式:

^{pr2}$

下面也可以工作,并且(控制台以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'

正是这种内部的编码/解码让我困惑,也让我有点困惑。在

确保您可以在错误消息中看到结果的一种方法是使用repr,或者更直接地使用%r,而不是{}:这永远不会失败(因为任何对象都有一个表示,并且所有表示都是ASCII格式,包括可能的转义序列),并且还显示(作为转义序列)可能不可见的字符。在

repr(和老式格式字符串中的'%r')委托给对象类型的__repr__特殊方法;每个对象类型负责知道如何在一个明确(不一定是超级可读)的ASCII字符串中最好地表示自己。字符串和字节序列尤其擅长于此,因此repr非常适合它们。在

OP已经做到了,但不喜欢结果的美观性(在err.messagerepr和{}的repr之间变化)。不幸的是,美学是repr最不重要的优先事项:相反,它都是关于完整、明确的信息。在

另一个想法是用一个永不失败的编码(一个解码每个字节,尽管可能是一个无意义的上下文字形),如“iso-8859-1”。但我相信,它并没有比repr有实质性的改进;美学上的改进是相当值得商榷的,而且在“完整、明确的信息”方面存在丢失的可能性。在

相关问题 更多 >