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



当我收到异常作为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 reprerr 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'

正是这种内部编码/解码让我感到困惑 - 并且仍然让我有点困惑。

最新更新