Mac OS X终端中的Python unicode

时间:2009-05-27 22:17:55

标签: python macos unicode terminal

有人可以向我解释这个奇怪的事情:

在python shell中,我输入以下西里尔字符串:

>>> 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 个答案:

答案 0 :(得分:16)

>>> 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

答案 1 :(得分:13)

从Python 2.6开始,您可以使用环境变量PYTHONIOENCODING告诉Python您的终端是否支持UTF-8。最简单的方法是将以下行添加到~/.bash_profile

export PYTHONIOENCODING=utf-8

Terminal.app showing unicode output from Python

答案 2 :(得分:9)

除了确保OS X终端设置为UTF-8之外,您可能希望将python sys默认编码设置为UTF-8或更高版本。在名为/Library/Python/2.5/site-packages的{​​{1}}中创建一个文件。在这个文件中:

sitecustomize.py

import sys sys.setdefaultencoding('utf-8') 方法仅供网站模块使用,并已从sys namespace once startup has completed中删除。因此,您需要启动一个新的python解释器才能使更改生效。您可以使用setdefaultencoding启动后随时验证当前的默认编码。

如果字符不是unicode并且您需要转换它们,请对字符串使用sys.getdefaultencoding()方法,以便将来自其他字符集的文本解码为unicode ...最好指定哪个字符集:

decode

答案 3 :(得分:3)

另外,请确保终端编码设置为Unicode / UTF-8(而不是ascii,这似乎是您的设置):

http://www.rift.dk/news.php?item.7.6

答案 4 :(得分:0)

unicode对象需要先进行编码才能在某些控制台上显示。尝试

u'абвгд'.encode()

而是将unicode编码为字符串对象(最有可能使用utf8作为默认编码,但取决于你的python配置)

答案 5 :(得分:0)

'абвгд'不是unicode字符串

u'абвгд'是一个unicode字符串

如果不对其进行编码,则无法打印unicode字符串。当您在应用程序中处理字符串时,您希望确保解码任何输入并编码任何输出。这样,您的应用程序将仅在内部处理unicode字符串,并以UTF8输出字符串。

供参考:

>>> 'абвгд'.decode('utf8') == u'абвгд'
>>> True