python2和python3的编码区别

在讨论两个版本python间编码区别前,需要理解计算机编码的问题。编码介绍网上有很多资料,不过这里我还是想按照自己的理解说一下。一方面为了文章的完整性,另一方面借此梳理一下编码知识。

计算机中只有0和1,一切都是有二进制表示,包括文本字符。当我们编辑文本"hello world"并保存,计算机首先把文本编码为二进制表示,然后再存储。当我们试图读取刚才保存的文本,首先也是读取二进制数据,然后通过解码,得到文本"hello world"。

上面过程提到的编码方式很多,最早的就是ascii编码,其使用一个8位二进制数可以表示常见的英文字母和符号。ascii码最多表示128个字符(因为规定第一位保留为0)。

ascii码对英语国家够用了,但对非英语国家不够用,比如德语,法语,汉字等字符超过128个,无法仅通过ascii编码解决,因此随后又出现很多其他的编码方式。

文本文件在保存时候,会选择编码方式,因此打开时,要知道其编码方式,用相同的方式解码。否则如果解码方式不一致,会导致乱码。由于互联网出现,需要一种统一编码方式,因此unicode码出现。

需要强调的是,unicode是一个“字符集”,而不是编码方式。它给全球每个字符规定了一个二进制表示,但没说明实际保存文本字符时候应该如何编码。与其对应的编码方式有utf-8,utf-16,utf-32等。最常用的是utf-8编码,16和32可以不考虑。至于utf-8和unicode的关系以及utf-8具体变吗规范,可以参考这个文章http://www.cnblogs.com/xuxyblog/p/4122996.html,里面说的很详细了,我总结一下,拿到一个字符,utf-8编码步骤是:

1、根据unicode字符对应表,得到其unicode码;

2、根据unicode码,确定其需要几个字节表示(1到4个字节);

3、根据字节数,确定其utf-8编码时,可用的编码位;

4、根据可用编码位和unicode码,得到utf-8编码。

现在看一下python2和python3的编码方式:

1、python2中字符类型:

str对象。str对象不是文本字符,当我们定义str对象,计算机会对其编码操作,至于采用什么编码方式,取决于系统。win默认是gbk,linux默认utf-8。比如:

>>> 'china'    #定义一个str对象

'china'    #这里实际进行了utf-8编码,不过英文字母的utf-8编码和ascii一样的

>>> '中国'    #定义一个str对象,中文

'\xe4\xb8\xad\xe5\x9b\xbd'    #默认进行utf-8编码

unicode对象。如u'aaa',表示unicode编码的文本字符。可以支持中文等其他非英语字符:

>>> u'中国'

u'\u4e2d\u56fd'    #没有进行编码操作,这里显示的是字符的unicode码

python2中还有形如b"hello"的定义方式,它和str对象是一样的。

python2中,unicode和str定义的字节串对象,都有encode和decode,但是不建议使用unicode的decode以及字节串的encode,这是python2的设计缺陷。

>>> u'中国'.encode("utf-8")

'\xe4\xb8\xad\xe5\x9b\xbd'    #这里对汉语进行utf-8编码,可以看到结果确实和上面我们直接定义'中国'的结果一致,因为都是 中国 两个字的utf-8编码

当然我们可以采用其他的编码,比如进行utf-16编码:

>>> u'中国'.encode('utf-16')

'\xff\xfe-N\xfdV'

>>> '中国'.decode('utf-8')    #这里将str进行utf-8解码,得到 中国 两个字的unicode码

u'\u4e2d\u56fd'

如果进行其他解码会报错,因为unix下默认编码是utf-8

>>> '中国'.decode('gbk')

Traceback (most recent call last):

  File "", line 1, in

UnicodeDecodeError: 'gbk' codec can't decode bytes in position 2-3: illegal multibyte sequence

2、python3中两种字符类型:

str对象。str对象本身就是文本字符,是unicode编码,对应于python2中的u'hello'。在python3中,没有形如u'hello'的定义。str可以支持非英语字符:

>>> 'china'

'china'

>>> '中国'

'中国'

bytes对象。bytes是字节串,其对应于python2中的str对象。

字节串和文本字符可以通过encode和decode相互转化

>>> '中国'.encode('utf-8')

b'\xe4\xb8\xad\xe5\x9b\xbd'

>>> b'\xe4\xb8\xad\xe5\x9b\xbd'.decode('utf-8')

'中国'

>>> '中国'.encode('gbk')

b'\xd6\xd0\xb9\xfa'

>>> b'\xd6\xd0\xb9\xfa'.decode('gbk')

'中国'


你可能感兴趣的:(编程,python)