python2.x和3.x中的字符串编码问题

       首先,由于计算机只能识别0和1,为了将字符串转化为机器可识别语言,程序会先把这个字符串内容进行编码成机器可识别的二进制数据。当涉及到一些比如文本I/O或数据存储等会包含编码解码过程的操作时,不清楚python的字符串编码解码过程,就容易引发错误,特别是在2.x和3.x的版本里,对字符串类型和编码解码方式做了较大的区分。

       在正式区分2.x和3.x的字符串编码解码问题之前,有必要先了解一下编码的大致历史。最初的编码方式是由美国推出的ASCII编码,这个是只针对一些常见字符的编码,由于字符不多,只用了127个码点,故只需要一个字节即可满足。但是随着不同国家对各自的字符的需求增加,一个字节的长度显然已经不能满足了,因此这个过程中逐渐在ASCII的基础上增加了新的字节添加了新的字符,产生了多种编码方式,程序的全球化以及为了方便程序和机器的交流,这种现象最终肯定是要回归大一统的,所以就形成了最后的万国码Unicode。什么是Unicode?从不同的角度可以进行不同的解读。从字符集合而言,Unicode可以被认为是全世界所有计算机字符的集合,并且是已经具有唯一确定字符到码点值映射的字符集合;从编码方案看,Unicode可以被认为是包含了各种不同的编码方案的集合,比如utf-8、utf-16等编码方案,Unicode下的不同的编码方案对应不同的字节储存方式,但是字符和码点值的映射是一样的。要注意的是,ASCII编码方式,即字符到码点值的映射,是Unicode的一个子集,也就是说,Unicode的码点映射是在ASCII的部分字符映射的基础上增加的,所以Unicode是兼容ASCII的。

       按正常的理解,字符串是一种数据类型,在有Unicode的前提下,字符串应该是字符的最终呈现形式,不能被继续解码,但是可以被编码成二进制数据,而且,系统默认的编码解码方式也应该是Unicode,故编码方案肯定也是Unicode下的一种。这是合理而正常的理解,如果你也有这种理解方式,那么恭喜你,python3.x真是按这样的理解方式来处理编码解码的,如果你一直用的是3.x版本,那么你其实不太会遇到编码解码的问题。具体来说,python3.x版本中,所有的字符串对象只有一个,就是str,其也是bytes对象解码的最终呈现形式,不可再被解码,而且,3.x版本里系统默认的编码方式就是Unicode编码方案中的utf-8

       相比而言,2.x版本中的字符串对象以及编码问题就显得有点不怎么规范,当然这是个历史遗留问题,最终不也是在3.x版本里面规范回来了吗。虽然不怎么规范,但是无奈当下2.x版本依然盛行,所以还是需要理解一下2.x版本中的字符串对象以及编码问题。在2.x中,有两种字符串类型,str和unicode,str仅仅只能表示由ASCII编码的字符组成的字符串类型,非ASCII字符串对象由unicode表示,一般地,‘s’对于str,u's'对于unicode,当然‘你好’也表示str,但是无法编码,因为这是非ASCII字符,要编码‘你好’,只能转成unicode后才行,即u‘你好’才可以被编码。这里还要注意的是,在2.x中,对于ASCII字符,str就相当于3.x中的bytes,str和bytes可以自由自动转换,所以对于ASCII字符,str被解码后是unicode,unicode被编码后是str,这里的str可以看做3.x的bytes类型。但是对于非ASCII字符,只能转成unicode后才能被编码。2.x中,系统默认的编码方式是ASCII,并且str的编码方式指定的就是ASCII,甚至无法显式更改,因此,当涉及非ASCII字符的str对象编码时,一定要先转成unicode类型并且显示指定Unicode的编码方式(一般是utf-8)才行,这就是为什么在2.x中为何对于中文字符串,都要在前面加入u,并且要指定utf-8编码方式的原因。

猜你喜欢

转载自blog.csdn.net/S_o_l_o_n/article/details/81748599