python中的unicode是让人很困惑、比较难以理解的问题,本文力求彻底解决这些问题;
1.unicode、gbk、gb2312、utf-8的关系;
http://www.pythonclub.org/python-basic/encode-detail
这篇文章写的比较好,utf-8是unicode的一种实现方式,unicode、gbk、gb2312是编码字符集;
2.python中的中文编码问题;
2.1 .py文件中的编码
Python 默认脚本文件都是 ANSCII 编码的,当文件 中有非 ANSCII 编码范围内的字符的时候就要使用"编码指示"来修正。 一个module的定义中,如果.py文件中包含中文字符(严格的说是含有非anscii字符),则需要在第一行或第二行指定编码声明:
# -*- coding=utf-8 -*-或者 #coding=utf-8 其他的编码如:gbk、gb2312也可以;
否则会出现类似:SyntaxError: Non-ASCII character '/xe4' in file ChineseTest.py on line 1, but no encoding declared; see
http://www.pytho
for details这样的异常信息;n.org/peps/pep-0263.html
2.2 python中的编码与解码
先说一下python中的字符串类型,在python中有两种字符串类型,分别是str和unicode,他们都是basestring的派生类;str类型是一个包含Characters represent (at least) 8-bit bytes的序列;unicode的每个unit是一个unicode obj;所以:
len(u'中国')的值是2;len('ab')的值也是2;
在str的文档中有这样的一句话:The string data type is also used to represent arrays of bytes, e.g., to hold data read from a file. 也就是说在读取一个文件的内容,或者从网络上读取到内容时,保持的对象为str类型;如果想把一个str转换成特定编码类型,需要把str转为Unicode,然后从unicode转为特定的编码类型如:utf-8、gb2312等;
python中提供的转换函数:
unicode转为 gb2312,utf-8等
# -*- coding=UTF-8 -*-
if __name__ == '__main__':
s = u'中国'
#s为unicode先转为utf-8
s_utf8 =s.encode('UTF-8')
assert(s_utf8.decode('utf-8') == s)
普通的str转为unicode
# -*- coding=UTF-8 -*-
if __name__ == '__main__':
s = '中国'
su = u'中国''
#s为unicode先转为utf-8
#因为s为所在的.py(# -*- coding=UTF-8 -*-)编码为utf-8
s_unicode =s.decode('UTF-8')
assert(s_unicode == su)
#s转为gb2312,先转为unicode再转为gb2312
s.decode('utf-8').encode('gb2312')
#如果直接执行s.encode('gb2312')会发生什么?
s.encode('gb2312')
# -*- coding=UTF-8 -*-
if __name__ == '__main__':
s = '中国'
#如果直接执行s.encode('gb2312')会发生什么?
s.encode('gb2312')
这里会发生一个异常:
Python 会自动的先将 s 解码为 unicode ,然后再编码成 gb2312。因为解码是python自动进行的,我们没有指明解码方式,python 就会使用 sys.defaultencoding 指明的方式来解码。很多情况下 sys.defaultencoding 是 ANSCII,如果 s 不是这个类型就会出错。
拿上面的情况来说,我的 sys.defaultencoding 是 anscii,而 s 的编码方式和文件的编码方式一致,是 utf8 的,所以出错了: UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
When Python executes a print statement, it simply passes the output to the operating system (using fwrite() or something like it), and some other program is responsible for actually displaying that output on the screen. For example, on Windows, it might be the Windows console subsystem that displays the result. Or if you're using Windows and running Python on a Unix box somewhere else, your Windows SSH client is actually responsible for displaying the data. If you are running Python in an xterm on Unix, then xterm and your X server handle the display.
To print data reliably, you must know the encoding that this display program expects.
Decodes the string using the codec registered for encoding. encoding defaults to the default string encoding. errors may be given to set a different error handling scheme. The default is 'strict', meaning that encoding errors raise UnicodeError. Other possible values are 'ignore', 'replace' and any other name registered via codecs.register_error, see section 4.8.1.