encode()和decode()
前⾔
python运⾏处理的是unicode码,保存显⽰是⾃动转换成utf-8 以节省空间
decode成unicode(解成Unicode)  encode成其他(编成其他)
⼀、encode()和decode()
字符串在Python内部的表⽰是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码, 即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另⼀种编码。
所以:其他编码.decode—>unicode    de—>其他编码
decode的作⽤是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表⽰将gb2312编码的字符串str1转换成unicode编码。
encode的作⽤是将unicode编码转换成其他编码的字符串,如de('gb2312'),表⽰将unicode编码的字符串str2转换成gb2312编码。
总得意思:想要将其他的编码转换成utf-8必须先将其解码成unicode然后重新编码成utf-8,它是以unicode为转换媒介的 如:s='中⽂'如果是在utf8的⽂件中,该字符串就是utf8编码,如果是在gb2312的⽂件中,则其编码为gb2312。这种情况下,要进⾏编码转换,都需要先⽤ decode⽅法将其转换成unicode编码,再使⽤encode⽅法将其转换成其他编码。通常,在没有指定特定的编码⽅式时,都是使⽤的系统默认编码创建的代码⽂件
廖雪峰关于编码讲解
字符编码
我们已经讲过了,字符串也是⼀种数据类型,但是,字符串⽐较特殊的是还有⼀个编码问题。
因为计算机只能处理数字,如果要处理⽂本,就必须先把⽂本转换为数字才能处理。最早的计算机在设计时采⽤8个⽐特(bit)作为⼀个字节(byte),所以,⼀个字节能表⽰的最⼤的整数就是255(⼆进制11111111=⼗进制255),如果要表⽰更⼤的整数,就必须⽤更多的字节。⽐如两个字节可以表⽰的最⼤整数是65535,4个字节可以表⽰的最⼤整数是4294967295。
由于计算机是美国⼈发明的,因此,最早只有127个字符被编码到计算机⾥,也就是⼤⼩写英⽂字母、数字和⼀些符号,这个编码表被称为ASCII编码,⽐如⼤写字母A的编码是65,⼩写字母z的编码是122。
但是要处理中⽂显然⼀个字节是不够的,⾄少需要两个字节,⽽且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,⽤来把中⽂编进去。
你可以想得到的是,全世界有上百种语⾔,⽇本把⽇⽂编到Shift_JIS⾥,韩国把韩⽂编到Euc-kr⾥,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语⾔混合的⽂本中,显⽰出来会有乱
码。
因此,Unicode字符集应运⽽⽣。Unicode把所有语⾔都统⼀到⼀套编码⾥,这样就不会再有乱码问题了。
Unicode标准也在不断发展,但最常⽤的是UCS-16编码,⽤两个字节表⽰⼀个字符(如果要⽤到⾮常偏僻的字符,就需要4个字节)。现代操作系统和⼤多数编程语⾔都直接⽀持Unicode。
现在,捋⼀捋ASCII编码和Unicode编码的区别:ASCII编码是1个字节,⽽Unicode编码通常是2个字节。
字母A⽤ASCII编码是⼗进制的65,⼆进制的01000001;
字符0⽤ASCII编码是⼗进制的48,⼆进制的00110000,注意字符'0'和整数0是不同的;
汉字中已经超出了ASCII编码的范围,⽤Unicode编码是⼗进制的20013,⼆进制的01001110 00101101。
你可以猜测,如果把ASCII编码的A⽤Unicode编码,只需要在前⾯补0就可以,因此,A的Unicode编码是00000000 01000001。
新的问题⼜出现了:如果统⼀成Unicode编码,乱码问题从此消失了。但是,如果你写的⽂本基本上全部是英⽂的话,⽤Unicode编码⽐ASCII编码需要多⼀倍的存储空间,在存储和传输上就⼗分不划算。
所以,本着节约的精神,⼜出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把⼀个Unicode字符根据不同的数字⼤⼩编码成1-6个字节,常⽤的英⽂字母被编码成1个字节,汉字通常是3个字节,只有很⽣僻的字符才会被编码成4-6个字节。如果你要传输的⽂本包含⼤量英⽂字符,⽤UTF-8编码就能节省空间:
字符ASCII Unicode UTF-8
A0100000100000000 0100000101000001
中x01001110 0010110111100100 10111000 10101101
从上⾯的表格还可以发现,UTF-8编码有⼀个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的⼀部分,所以,⼤量只⽀持ASCII编码的历史遗留软件可以在UTF-8编码下继续⼯作。
搞清楚了ASCII、Unicode和UTF-8的关系,我们就可以总结⼀下现在计算机系统通⽤的字符编码⼯作⽅式:
在计算机内存中,统⼀使⽤Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
⽤记事本编辑的时候,从⽂件读取的UTF-8字符被转换为Unicode字符到内存⾥,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到⽂件:
浏览⽹页的时候,服务器会把动态⽣成的Unicode内容转换为UTF-8再传输到浏览器:
所以你看到很多⽹页的源码上会有类似<meta charset="UTF-8" />的信息,表⽰该⽹页正是⽤的UTF-8编码。
Python的字符串
搞清楚了令⼈头疼的字符编码问题后,我们再来研究Python的字符串。
在最新的Python 3版本中,字符串是以Unicode编码的,也就是说,Python的字符串⽀持多语⾔,例如:
>>> print('包含中⽂的str')
包含中⽂的str
对于单个字符的编码,Python提供了ord()函数获取字符的整数表⽰,chr()函数把编码转换为对应的字符:
>>> ord('A')
65
>>> ord('中')
20013
>>> chr(66)
'B'
>>> chr(25991)
'⽂'
如果知道字符的整数编码,还可以⽤⼗六进制这么写str:
>>> '\u4e2d\u6587'
'中⽂'
两种写法完全是等价的。
由于Python的字符串类型是str,在内存中以Unicode表⽰,⼀个字符对应若⼲个字节。如果要在⽹络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes。
Python对bytes类型的数据⽤带b前缀的单引号或双引号表⽰:
x = b'ABC'
要注意区分'ABC'和b'ABC',前者是str,后者虽然内容显⽰得和前者⼀样,但bytes的每个字符都只占⽤⼀个字节。
以Unicode表⽰的str通过encode()⽅法可以编码为指定的bytes,例如:
>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中⽂'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中⽂'.encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
纯英⽂的str可以⽤ASCII编码为bytes,内容是⼀样的,含有中⽂的str可以⽤UTF-8编码为bytes。含有中⽂的str⽆法⽤ASCII编码,因为中⽂编码的范围超过了ASCII编码的范围,Python会报错。
在bytes中,⽆法显⽰为ASCII字符的字节,⽤\x##显⽰。
反过来,如果我们从⽹络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要⽤decode()⽅法:
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中⽂'
如果bytes中包含⽆法解码的字节,decode()⽅法会报错:
>>> b'\xe4\xb8\xad\xff'.decode('utf-8')
Traceback (most recent call last):
...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte
如果bytes中只有⼀⼩部分⽆效的字节,可以传⼊errors='ignore'忽略错误的字节:
>>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
'中'
要计算str包含多少个字符,可以⽤len()函数:
>>> len('ABC')
3
>>> len('中⽂')
2
len()函数计算的是str的字符数,如果换成bytes,len()函数就计算字节数:
>>> len(b'ABC')
3
unicode码和ascii码区别
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中⽂'.encode('utf-8'))
6
可见,1个中⽂字符经过UTF-8编码后通常会占⽤3个字节,⽽1个英⽂字符只占⽤1个字节。
在操作字符串时,我们经常遇到str和bytes的互相转换。为了避免乱码问题,应当始终坚持使⽤UTF-8编码对str和bytes进⾏转换。
由于Python源代码也是⼀个⽂本⽂件,所以,当你的源代码中包含中⽂的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在⽂件开头写上这两⾏:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
第⼀⾏注释是为了告诉Linux/OS X系统,这是⼀个Python可执⾏程序,Windows系统会忽略这个注释;
第⼆⾏注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中⽂输出可能会有乱码。
申明了UTF-8编码并不意味着你的.py⽂件就是UTF-8编码的,必须并且要确保⽂本编辑器正在使⽤UTF-8 without BOM编码:
如果.py⽂件本⾝使⽤UTF-8编码,并且也申明了# -*- coding: utf-8 -*-,打开命令提⽰符测试就可以正常显⽰中⽂:
格式化
最后⼀个常见的问题是如何输出格式化的字符串。我们经常会输出类似'亲爱的xxx你好!你xx⽉的话费是xx,余额是xx'之类的字符串,⽽xxx的内容都是根据变量变化的,所以,需要⼀种简便的格式化字符串的⽅式。
在Python中,采⽤的格式化⽅式和C语⾔是⼀致的,⽤%实现,举例如下:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。