Mac OS X 终端中的 Python Unicode
有人能给我解释一下这个奇怪的事情吗:
当我在Python的命令行中输入以下这个西里尔字母的字符串:
>>> print 'абвгд'
абвгд
但是当我输入:
>>> print u'абвгд'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-9: ordinal not in range(128)
因为第一个字符串显示得很正常,我觉得我的OS X终端可以显示unicode字符,但在第二种情况下却显示不出来。为什么会这样呢?
6 个回答
除了确保你的 OS X 终端设置为 UTF-8 编码外,你可能还想把 Python 的默认编码设置为 UTF-8 或更好的编码。你需要在 /Library/Python/2.5/site-packages
目录下创建一个名为 sitecustomize.py
的文件。在这个文件里写入:
import sys
sys.setdefaultencoding('utf-8')
这里的 setdefaultencoding
方法只能通过 site 模块使用,而且在程序启动完成后,它会从 sys 命名空间 中移除。因此,你需要重新启动一个新的 Python 解释器,才能让这个设置生效。你可以在启动后随时用 sys.getdefaultencoding()
来检查当前的默认编码。
如果字符还不是 Unicode 格式,而你需要转换它们,可以在字符串上使用 decode
方法,将文本从其他字符集解码为 Unicode... 最好指定一下使用的字符集:
s = 'абвгд'.decode('some_cyrillic_charset') # makes the string unicode
print s.encode('utf-8') # transform the unicode into utf-8, then print it
从Python 2.6开始,你可以使用一个叫做PYTHONIOENCODING
的环境变量来告诉Python,你的终端支持UTF-8编码。为了让这个设置永久生效,最简单的方法是在你的~/.bash_profile
文件中添加以下一行:
export PYTHONIOENCODING=utf-8
>>> print 'абвгд'
абвгд
当你在终端输入一些字符时,终端会决定这些字符是如何传递给应用程序的。终端可能会把字符以utf-8、ISO-8859-5或者其他只有终端能理解的方式编码。Python接收到的这些字符其实是一串字节。然后,Python会直接把这些字节打印出来,而终端会以某种方式解读这些字节来显示字符。因为终端通常会以和之前编码时相同的方式解读字节,所以你看到的内容就和你输入的一样。
>>> u'абвгд'
在这里,你输入的字符会以字节的形式到达Python解释器,可能是通过终端以某种方式编码的。使用u
前缀,Python会尝试把这些数据转换成unicode格式。为了正确转换,Python需要知道你的终端使用的编码方式。在你的情况下,Python猜测你的终端编码是ASCII,但接收到的数据和这个不匹配,因此你会遇到编码错误。
所以,在交互式会话中创建unicode字符串的简单方法就是这样:
>>> us = 'абвгд'.decode('my-terminal-encoding')
在文件中,你也可以通过一个特殊的模式行来指定文件的编码:
# -*- encoding: ISO-8859-5 -*-
us = u'абвгд'
关于设置默认输入编码的其他方法,你可以查看sys.setdefaultencoding(...)
或者sys.stdin.encoding
。