众所周知Python的内码编码是Unicode,所有输入的编码都需要转换成unicode然后转出成为其他编码。Python2中存在unicode对象和str对象两种,在中文处理的时候很容易出问题,而Python3直接全部统一了编码到unicode。

举一个例子说明编码的转换,首先我们的环境是utf-8

LANG=zh_CN.UTF-8
LANGUAGE=zh_CN:zh
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_PAPER="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=zh_CN.UTF-8

然后测试一个从环境的输入和写回到环境。

文件编码gbk:
print '中文'
print u'中文'
输出
    ����
    中文

文件编码utf-8
print '中文'
print u'中文'

输出
    中文
    中文

说明print输出的时候按照default encoding进行了编码。所以只有gbk的编码乱码了。同样对输入的判断,环境如果是utf8,输出不变的话,不会有乱码。但是如果从文件里读取了字符串或者代码里有硬编码字符,就需要考虑编码了。另外,unicode和str相加会有编码问题。比如:

文件编码gbk:    
value = raw_input()
print value + "中文"
输入
    中文
输出
    中文����

value = raw_input()
print value + u"中文"
输入
    en
输出
    en中文
输入
    中文
输出
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

str+str输出肯定是str,所以需要适配环境的编码,第一个乱码可以理解。而str+unicode的时候,str会被按default encoding解码。utf8无法按照python default encoding ascii解码。utf8文件编码下的情况类似。

本文版权归CXH_ME所有,原创不易,人艰不抄,转载还请注明出处,谢谢