unicode 只定义字符对应的数字,但没有规定这些数字如何存储起来,比如像中文的『我』字存储时需要两个字节来表示,而英文字母A却只需要一个字节,有些其他的字符可能需要3-4个字节。
utf-8 是对 unicode 编码存储的一种实现方式,同样的还有 utf-16, utf-32。
utf-8 是使用最广泛的编码方式,采用变长的编码方式,可以使用1-4个字节来表示一个字符; utf-16 用2个或4个字节,utf-32 用4个字节表示。编码规则如下:
python2 中有字符串类型有两种:byte string (str)
和 unicode string (unicode)
。
1 2 3 4 5 6 7 8 9 | >>> s = '美的' >>> s '\xe7\xbe\x8e\xe7\x9a\x84' >>> s = u'美的' >>> s u'\u7f8e\u7684' >>> s = '美的' >>> s.decode('utf-8') u'\u7f8e\u7684' |
上面的输出中,第一个s的类型是 str,打印出来的内容是 utf-8 编码过的内容。第二个s的类型是 unicode,打印出来的两个双字节的数字分别表示了两个汉字『美的』。
encode
和decode
提供 str 和 unicode 这两种的类型的互相转化。
本质上,str是存放的字节序,有可能是 ascii, gbk, utf-8 等等中的任意一种,通过调用 decode 可以把他们转化成 unicode ,默认的 decode 编码是 ascii 。str中到底是用的哪一种编码,取决于它所在的场景,跟 locale ,文件编码等等都有关系。
1 2 3 4 5 6 | #!/usr/bin/env python # -*- coding: GBK -*- s = u'中文' print repr(s) print repr(s.encode('GBK')) |
比如上面的文件enc.py
,保存的时候选择文件编码
是GBK,程序文件本质上也是文件,当我们使用某个外部的应用 打开它时(编辑器或者python解释器等),外部应用是不知道该文件的编码格式的,
这个时候有三种情况:
# -*- coding: GBK -*-
告知解释器使用GBK来解码;试验一下,把# -*- coding: GBK -*-
删除后,执行python enc.py
,输出:
1 2 | File "enc.py", line 4 SyntaxError: Non-ASCII character '\xd6' in file enc.py on line 4, but no encoding declared; |
试着用vim打开该文件时,『中文』两个字就会显示成乱码,因为vim默认的文件编码方式被设置成UTF-8了。
1 2 3 4 5 6 7 8 9 10 11 12 | #!/usr/bin/env python # -*- coding: GBK -*- s1 = u'中文' print repr(s1) print repr(s1.encode('GBK')) s2 = '中文' print repr(s2) print repr(s2.decode('GBK')) |
输出结果:
1 2 3 4 | u'\u4e2d\u6587' '\xd6\xd0\xce\xc4' '\xd6\xd0\xce\xc4' u'\u4e2d\u6587' |
从这里可以看出来, s2中存放的是byte格式的从文件中读到的GBK编码的内容。
再看下面的这段代码,程序文件utf8_enc.py
,保存成UTF-8编码的。
1 2 3 4 5 6 7 8 9 10 11 12 | #!/usr/bin/env python # -*- coding: utf-8 -*- s1 = u'中文' print repr(s1) print repr(s1.encode('GBK')) s2 = '中文' print repr(s2) print repr(s2.decode('GBK')) |
输出:
1 2 3 4 5 6 7 | u'\u4e2d\u6587' '\xd6\xd0\xce\xc4' '\xe4\xb8\xad\xe6\x96\x87' Traceback (most recent call last): File "unicode_enc.py", line 12, in <module> print repr(s2.decode('GBK')) UnicodeDecodeError: 'gbk' codec can't decode bytes in position 2-3: illegal multibyte sequence |
这里同样可以知道,s2中存放的是文件保存的编码UTF-8的byte码。
http://www.rrn.dk/the-differe…
http://www.ruanyifeng.com/blo…
https://docs.python.org/2/how…
http://yergler.net/2012/bytes…
联系客服