ASCII, Unicode , GBK, UTF-8
上面这四个东东是两个层面上的东西,不能混为一谈。
ASCII和Unicode一类,都是一种字符编码标准,里面包含了字符集,编码格式。既然是标准,那么就是一种约定俗成的东西。
这是广义上的定义,我们一般说的ASCII和Unicode是指字符集。
GBK和UTF-8对等,它们分别是ASCII和Unicode两种标准下的一种编码格式。
编码格式是用来存储和传输的,用于将字符集中的code point转化为机器码(二进制码)
参考:网页编码就是那点事
Python 2.x str & unicode
python里的unicode就不是上面所说的标准或者字符集了,而是python定义的一种类型。
str可以认为是编码之后的字符串,它可以通过encode和decode这两个方式实现和unicode的相互转换。
注意:str的编码格式,如果是在解释器中输入的,则取决于解释器的默认编码,比如是在iterm中运行解释器,那么编码格式就由iterm的编码格式决定;如果是保存到文件中的,则取决于文件保存的编码格式,比如文件的编码格式是utf-8 ,那么解释器读取str的时候就是utf-8de编码格式。
encode和decode
# -*- coding: utf-8 -*-
s = '知行合一'
# s是一个utf-8格式的字符串
us = s.decode('utf-8')
# s被解码为unicode对象,赋值给us
ss = us.encode('gbk')
# us被编码成gbk格式的字符串,赋值给ss
但是事实情况要比这个复杂,比如看如下代码:
# -*- coding: utf-8 -*-
s = "知行合一"
s.encode('gbk')
看!str也能编码,(事实上unicode对象也能解码,但是意义不大)
为什么可以这样呢?其实str还是做了解码操作,只是这里的解码操作被隐藏起来了。流程还是和上面的一样,当对s进行编码之前,先会用默认的编码对s进行解码,再用解码之后的unicode对象进行编码。
这就引出了python2.x中在处理中文时,大多数出现错误的原因所在:python的默认编码,defaultencoding是ascii
还是上面的例子,上面的代码会报错,错误信息:UnicodeDecodeError: ‘ascii’ codec can’t decode byte ……
因为没有指定defaultencoding,所以它其实是在做这样的事情
# -*- coding: utf-8 -*-
s = "知行合一"
s.decode('ascii').encode('gbk')
显然中文字符超出了ASCII字符集的范围,出现解码错误
解决方法:
在文件的头部用# -*- coding:utf-8 -*-指明编码格式,并且保存文件的时候要选择相同的编码格式。