解码函数试图编码Python

7 投票
3 回答
6096 浏览
提问于 2025-04-16 10:37

我正在尝试打印一个unicode字符串,但不想让它里面包含特定的编码十六进制值。我从Facebook获取这些数据,网页的编码类型是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 个回答

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中消失了,因为它让人困惑。

3

当你在控制台打印内容时,Python会尝试把字符串转换成你终端使用的字符集。如果这个字符集不是UTF-8,或者不能表示字符串中的所有字符,Python就会发出警告并抛出错误。

我有时候在快速处理数据时会遇到这个问题,比如数据中包含土耳其字符。

如果你是在Windows命令提示符下运行python.exe,可以在这里找到一些解决方案:cmd.exe使用的是什么编码/代码页。简单来说,你可以用chcp命令来更改代码页,但这个过程有点麻烦。我建议你参考Mark的建议,使用像IDLE这样的工具。

8

其实不是解码出问题了,而是你在尝试把结果显示到控制台上。当你使用print的时候,它会用默认的编码方式(ASCII)来处理字符串。所以如果你不使用print,这个问题就能解决了。

>>> a=u'really long string containing \\u20ac and some other text'
>>> type(a)
<type 'unicode'>
>>> a.decode('unicode-escape')
u'really long string containing \u20ac and some other text'
>>> print a.decode('unicode-escape')
Traceback (most recent call last):
  File "<stdin>", line 1, in 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 30: ordinal not in range(128)

我建议你使用IDLE或者其他可以输出unicode的解释器,这样就不会遇到这个问题了。


更新:请注意,这和少一个反斜杠的情况不一样,后者是在解码时出错,但错误信息是一样的:

>>> a=u'really long string containing \u20ac and some other text'
>>> type(a)
<type 'unicode'>
>>> a.decode('unicode-escape')
Traceback (most recent call last):
  File "<stdin>", line 1, in 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 30: ordinal not in range(128)

撰写回答