在发送到终端之前,Python 2.7解释器使用什么编码方案来编码Unicode代码点?

时间:2016-01-03 16:08:08

标签: python python-2.7 unicode encoding utf-8

我正在使用python 2.7。我的终端的编码方案设置为'utf-8'。 Python的默认编码方案是'ascii'。

>>> sys.getdefaultencoding()
'ascii'

写作时

>>> print(u'à')
à

我的终端上显示正确的Unicode字符。我没有得到python解释器用来编码Unicode代码点的编码方案,然后再将它发送到终端。是UTF-8吗?但是python的默认编码方案设置为'ascii'。它如何决定使用UTF-8进行编码。

编辑:
我知道我可以自己指定编码如下:

>>> print(u'à'.encode('utf-8'))
à

但是当我没有指定编码时,我想知道它是如何工作的。

2 个答案:

答案 0 :(得分:2)

Python尝试确定终端编码,并在打印到终端时使用该编码。 sys.stdout.encoding包含检测到的编码。 getdefaultencoding()是在未指定编码时用于编码Unicode字符串的编码。

示例(Windows控制台中的Python 2):

>>> import sys
'ascii'
>>> sys.stdout.encoding
'cp437'

打印到终端使用sys.stdout.encoding。我使用终端编码中无效的Unicode字符来查看错误消息中的编码:

>>> print u'\xc1'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\encodings\cp437.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character u'\xc1' in position 0: character maps to <undefined>

此处我没有指定编码,它使用默认值:

>>> u'\xc1'.encode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xc1' in position 0: ordinal not in range(128)

示例(Windows控制台中的Python 3):

>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
>>> sys.stdout.encoding
'cp437'

打印仍然使用sys.stdout.encoding

>>> print('\xc1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\dev\Python35\lib\encodings\cp437.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\xc1' in position 0: character maps to <undefined>

但编码默认为Python 3的默认值utf-8

>>> '\xc1'.encode()
b'\xc3\x81'

重定向输出

重定向Python脚本的输出时,sys.stdout.encoding的值可能会发生变化。这可以使用PYTHONIOENCODING环境变量覆盖。

Python 2重定向不会检测编码。它将默认为ascii

C:\>py -2 -c "import sys;print(sys.stdout.encoding)" | more
None

Python 3使用ANSI编码(因Windows本地化版本而异):

C:\>py -3 -c "import sys;print(sys.stdout.encoding)" | more
cp1252

覆盖环境变量:

C:\>set PYTHONIOENCODING=utf8

C:\>py -2 -c "import sys;print(sys.stdout.encoding)" | more
utf8

C:\>py -3 -c "import sys;print(sys.stdout.encoding)"
utf8

答案 1 :(得分:0)

显然,python从路径中的sys.stdout变量中选择LC_CTYPE的编码方案。

ayush:~$ export LC_CTYPE=POSIX python
ayush:~$ python
Python 3.5.1 |Continuum Analytics, Inc.| (default, Dec  7 2015, 11:16:01) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.stdout.encoding
'ANSI_X3.4-1968'