看了n多篇文章之后终于明白了文字编码和python处理的机制,老了。。。
记录如下
常用编码:gb系列(gb2312, gbk, gb18030向前兼容,越在后面出现的编码规范,所能表示的文字范围大,但是相同字符,只要能够表示,则表示法相同),unicode, ascii
这几种编码方式和utf-8的关系是:
前面几种说的是二进制byte序列和字符的对应关系,而utf-8则是unicode编码的表示方式。详细参照之前的一篇转载
两类“编码”都是映射,gb系列,ascii,unicode是(字符,二进制)的映射,而utf-8是(unicode,二进制)的映射
我们以两个字符串“4G”,“内存”为例,
gb、unicode、ascii对应英文字符、数字的编码是相同的都是ascii表中的值,也即“4G”这个字符串在这三种编码下的表示都是一样的都是:\x34\x47
但是对于“内存”这个中文字符串来说表示法就不一样了:
gb类:\xc4\xda\xb4\xe6
unicode:\x51\x85\x5b\x58
ascii:无法表示,因为ascii只能表示128种状态,无法对中文编码
utf-8:\xe5\x86\x85\xe5\xad\x98
在python中,以unicode为中心(对应unicode类,如 u"string",u"内存"都是unicode的对象),python支持unicode到其他编码的转换:
encode:将unicode转为其他编码
- u"内存".encode("gb18030")将unicode转为gb18030;
- u"4G".encode("ascii")将unicode转为ascii编码;
- u"内存".encode("ascii")试图将unicode转为ascii,但是将得到一个异常,因为ascii不可能表示汉字;
- u"4G内存".encode("utf-8")将unicode转为utf-8
decode:将其他编码转为unicode
- u"内存".encode("gb18030").decode("gb18030")将unicode转为gb18030后在转回来
与decode等价的函数为构造函数unicode("内存","utf-8");
有意思的是虽然python将unicode作为转换的中心(理应支持最多),但是默认输出的code却为ascii码,也即我们print u"内存"时会因为unicode对象不符合ascii编码而导致print抛出异常,其他几种编码则无这种问题,也即,如下几种写法对于print是合理的:
- print u"内存".encode("gb18030");
- print u"内存".encode("utf-8");
- print u"内存".encode("ascii");
如果你实际操作,会发现最后一条语句仍然会抛出异常,但那是unicode转为ascii时抛出的,不是print所抛出的。