无法在OS X终端APP中解码Python的UTF-8字符串

4 投票
4 回答
9608 浏览
提问于 2025-04-15 11:16

我在终端应用程序里设置了接受utf-8编码,这样在bash里我可以输入Unicode字符,还能复制和粘贴。但是一旦我打开Python的命令行,就不能输入这些字符了,而且如果我尝试解码Unicode,就会出现错误。

>>> wtf = u'\xe4\xf6\xfc'.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
>>> wtf = u'\xe4\xf6\xfc'.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

有没有人知道我哪里出错了?

4 个回答

3

在编程中,有时候我们会遇到一些问题,比如代码运行不正常或者出现错误。这些问题可能是因为我们写的代码有bug,或者是因为我们没有正确理解某些概念。

当我们在网上寻找解决方案时,StackOverflow是一个非常有用的地方。在那里,很多程序员会分享他们遇到的问题和解决办法。你可以在上面找到很多关于编程的讨论和建议,帮助你更好地理解代码。

如果你在学习编程,遇到困难时,可以去看看这些讨论,可能会找到你需要的答案。记得多动手实践,慢慢就会掌握这些知识。

>>> wtf = '\xe4\xf6\xfc'
>>> wtf
'\xe4\xf6\xfc'
>>> print wtf
���
>>> print wtf.decode("latin-1")
äöü
>>> wtf_unicode = unicode(wtf.decode("latin-1"))
>>> wtf_unicode
u'\xe4\xf6\xfc'
>>> print wtf_unicode
äöü
4

我觉得你搞错了编码和解码的顺序。你应该是把Unicode编码成字节流,然后再把字节流解码成Unicode。

Python 2.6.1 (r261:67515, Dec  6 2008, 16:42:21) 
[GCC 4.0.1 (Apple Computer, Inc. build 5370)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> wtf = u'\xe4\xf6\xfc'
>>> wtf
u'\xe4\xf6\xfc'
>>> print wtf
äöü
>>> wtf.encode('UTF-8')
'\xc3\xa4\xc3\xb6\xc3\xbc'
>>> print '\xc3\xa4\xc3\xb6\xc3\xbc'.decode('utf-8')
äöü
18

我觉得这里面有很多关于编码和解码的混淆。你一开始有一个unicode对象:

u'\xe4\xf6\xfc'

这是一个unicode对象,这三个字符是“äöü”的unicode编码点。如果你想把它们变成Utf-8格式,你需要编码它们:

>>> u'\xe4\xf6\xfc'.encode('utf-8')
'\xc3\xa4\xc3\xb6\xc3\xbc'

结果会得到六个字符,这就是“äöü”的Utf-8表示。

如果你调用decode(...),你就是在尝试把这些字符当作某种编码来解释,而这些编码还需要转换成unicode。因为它已经是unicode了,所以这样做是行不通的。第一次调用尝试把Ascii转换成unicode,第二次调用则是Utf-8转换成unicode。由于u'\xe4\xf6\xfc'既不是有效的Ascii也不是有效的Utf-8,所以这些转换尝试都会失败。

更让人困惑的是,'\xe4\xf6\xfc'也是“äöü”的Latin1/ISO-8859-1编码。如果你写一个普通的python字符串(没有前面的“u”,表示它不是unicode),你可以用decode('latin1')把它转换成unicode对象:

>>> '\xe4\xf6\xfc'.decode('latin1')
u'\xe4\xf6\xfc'

撰写回答