解码函数尝试对Python进行编码

7
我正在尝试打印一个没有特定编码十六进制的Unicode字符串。我正在从Facebook获取这些数据,它在HTML头中具有UTF-8编码类型。当我打印类型时,它说它是Unicode,但是当我尝试使用unicode-escape解码它时,会出现编码错误。为什么在使用解码方法时它会尝试进行编码?
代码:
a='really long string of unicode html text that i wont reprint'
print type(a)
 >>> <type 'unicode'>   
print a.decode('unicode-escape')
 >>> Traceback (most recent call last):
  File "scfbp.py", line 203, in myFunctionPage
    print a.decode('unicode-escape')
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 1945: ordinal not in range(128)
3个回答

8
这不是解码失败的问题,而是因为您试图在控制台中显示结果。当您使用print时,它会使用默认编码ASCII对字符串进行编码。不要使用print,就可以正常工作。
建议使用IDLE或其他能够输出Unicode的解释器,这样就不会出现这个问题。
更新:请注意,这与少一个反斜杠的情况不同,在那种情况下,解码失败并出现相同的错误消息。

这不是他错误的原因。他正在尝试解码Unicode对象。由于你从二进制数据解码为Unicode数据,Python 2会首先编码它,使用ASCII编解码器。这就是失败的原因。 - Lennart Regebro
@Lennart Regebro:同时在他的问题中,他陈述道:“我正在尝试打印一个没有特定编码十六进制的Unicode字符串。”这对我来说意味着他正在尝试将编码数据转换为可读性强的(Unicode)字符串,以便正确显示(作为字符,而不是代码)。使用解码确实是正确的方法。如果你注意到,“交互式控制台”输出显然是伪造的。 - Mark Byers
@Lennart Regebro:另外,即使字符串实际上是Unicode字符串,它仍然可能只包含有效的ASCII字符。例如,它可能是字符串u'\\u2110' - 这是一个包含六个Unicode字符的字符串(而不是一个 - 注意反斜杠被转义了)。然后从unicodestr的自动转换将成功,但打印仍将因为他得到的错误而失败。 - Mark Byers
@Mark Byers:如果终端编码是ASCII,即使他正确地打印了Unicode字符串(不确定如何测试),他可能会遇到此错误,但这似乎有点不太可能。与他只是对Unicode感到困惑相比,这种情况发生在大多数人身上。 :) - Lennart Regebro
1
@Lennart Regebro:我已经在我的回答中添加了更多细节。正如您所看到的,错误消息可能是两种完全不同情况的结果,具体取决于原始字符串是否包含Unicode字符或Unicode转义代码。我不认为您能够更能够说出哪个是“正确”的答案 - 只有OP知道那个。但是,考虑到他问题中的所有信息,我个人认为最有可能的解释是我最初给出的解释。而且,我认为仅根据问题中的信息就足以声称我的答案是错误的证据不足。 - Mark Byers
显示剩余3条评论

3
当你向控制台打印时,Python会尝试将字符串编码(转换)为终端的字符集。如果不是UTF-8,或者不能映射字符串中所有字符的字符集,它会发出警告并抛出异常。
这在我处理数据时经常遇到问题,例如其中包含土耳其字符。
如果你通过Windows命令提示符运行python.exe,你可以在这里找到一些解决方案:cmd.exe使用的编码/代码页。基本上,你可以用chcp改变代码页,但这很繁琐。我会遵循Mark的建议,使用像IDLE这样的工具。

2
>>> print type(a)
<type 'unicode'>
>>> a.decode('unicode-escape')

为什么使用解码方法时会尝试进行编码?
因为你使用解码方法将字符串转换为 Unicode 格式,而编码方法则是从 Unicode 转换为其他格式。你刚刚尝试将 Unicode 字符串解码成 Unicode 格式,之后它会尝试使用 ASCII 编码方式将其转换为字符串,这就是为什么会出现如下结果的原因:
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2110' in position 3: ordinal not in range(128)

请记住:Unicode不是一种编码方式。其他编码方式都是,例如ascii、utf8、latin-1等。

顺带一提,这种隐式编码在Python 3中已经消失了,因为它容易让人感到困惑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接