无法在OS X终端APP中解码Python的UTF-8字符串
我在终端应用程序里设置了接受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 个回答
在编程中,有时候我们会遇到一些问题,比如代码运行不正常或者出现错误。这些问题可能是因为我们写的代码有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
äöü
我觉得你搞错了编码和解码的顺序。你应该是把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')
äöü
我觉得这里面有很多关于编码和解码的混淆。你一开始有一个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'