先看代码
>>> a = ‘中文‘
>>> a
‘中文‘
>>> print(a)
中文
>>> b = ‘English‘
>>> b
‘English‘
>>> print(b)
English
解释编码和解码的过程
>>> aa = a.encode(‘utf-8‘)
>>> aa
b‘\xe4\xb8\xad\xe6\x96\x87‘
>>> a.encode(‘gbk‘)
b‘\xd6\xd0\xce\xc4‘
>>> aa.decode(‘utf-8‘)
‘中文‘
>>> type(a)
<class ‘str‘>
>>> type(aa)
<class ‘bytes‘>
>>> ‘\u4e2d\u6587
‘‘中文‘
>>> print(‘\u4e2d\u6587‘)
中文
>>> b.encode(‘ascii‘)
b‘English‘
>>> b.encode(‘utf-8‘)
b‘English‘
>>> b.encode(‘gbk‘)
b‘English‘
1.编码与解码
首先要知道python3中涉及到编码与解码的主要只有两个方法:编码encode和解码decode
编码(encode)过程是将Unicode形式转化为utf-8等其他形式
解码(decode)过程是将utf-8等其他形式转化为Unicode形式
这里一定一定要注意,要把Unicode和utf-8等其他形式区分来看待,Unicode自己是一类,其他形式合在一起是一类
Unicode形式的字符串的type是str,utf-8等其他形式的字符串的type是bytes
可以理解成Uincode就是我们看到的字符本身,utf-8等其他形式是存储进文件时的格式
Unicode形式的字符串用print打印出来就是我们看到的字符,其他格式print都是一些16进制数
在python3中不涉及与文件、网页交互时,不涉及到编码解码,也不会涉及到乱码之类的问题,上面展示的只供学习使用(而python2是涉及的,因此很多人会说弃用py2改用py3就没有编码问题了,说的就是这里)
python3中a = ‘中文‘这样赋值默认a的编码方式是Unicode,encode之后得到的aa是二进制格式(二进制和16进制本质上是一样的)
编码和解码过程是这样的:比如一串字符,最初以GBK编码格式存在文件中,我们想将其变成UTF-8编码。需要先用GBK编码将原始的二进制数翻译成字符,即由GBK编码向Unicode编码进行转换,这是解码过程;得到字符之后再去找这些字符在UTF-8编码下对应什么二进制数,这些二进制数就是我们要的结果,这是编码过程,由Unicode向UTF-8编码的转换。所以Unicode相当于一个中介,所有编码的相互转化都要经过它。
2.编码的形式解读
首先要熟悉python中出现的编码形式,有时可以根据它的形式来判断这是什么编码
‘\u4e2d\u6587‘就是中文二字对应的Unicode编码
b‘\xe4\xb8\xad\xe6\x96\x87‘就是中文二字对应的utf-8编码
b‘\xd6\xd0\xce\xc4‘就是中文二字对应的gbk编码
其中\u和\x都是转义字符,和\n换行符类似
\x表示十六进制数,每个\x后面跟两位,每一位都是0-9abcdef这16个中的一个。两位共可以表示16*16=256个数,即可以表示2^8=2568位的二进制数可以表示的数。也就是说一个\x可以代表一个字节
\u表示Unicode编码,一个\u后面接4位的16进制数,每一位也是0-9abcdef这16个中的一个,4位可以表示16位二进制数可以表示的数,所以说一个\u可以代表两个字节
从字节的角度我们再来看一下这个输出,“中文”两个字
在Unicode编码中占4个字节
在utf-8编码中占6个字节
在gbk编码中占4个字节
这个结果和我们之前所说的一个中文字符在各个编码中占字节数相符
再注意到‘\u4e2d\u6587‘直接输出和print都会出现“中文”二字,进一步说明python3中我们通常说的字符其实就是Unicode,将他们看成完全一样的就好
输出‘\u4e2d\u6587‘这种转义字符时,是识别了\u,自动通过对照表将后面的那串字节显示成了中文
对于b‘‘这种前面有个b的,type都变了,不是str而是bytes,这种在print时会原样输出