1、什么是编码html
编码是指信息从一种形式或格式转换为另外一种形式或格式的过程。python
在计算机中,编码,简而言之,就是将人可以读懂的信息(一般称为明文)转换为计算机可以读懂的信息。众所周知,计算机可以读懂的是高低电平,也就是二进制位(0,1组合)。python3.x
而解码,就是指将计算机的可以读懂的信息转换为人可以读懂的信息。网络
2、 编码的发展渊源编辑器
以前的博客中已经提过,因为计算机最先在美国发明和使用,因此一开始人们使用的是ASCII编码。ASCII编码占用1个字节,8个二进制位,最多可以表示2**8=256个字符。函数
随着计算机的发展,ASCII码已经不能知足世界人民的需求。由于世界各国语言繁多,字符远远超过256个。因此各个国家都在ASCII基础上搞本身国家的编码。优化
例如中国,为了处理汉字,设计了GB2312编码,一共收录了7445个字符,包括6763个汉字和682个其它符号。1995年的汉字扩展规范GBK1.0收录了21886个符号。2000年的 GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。编码
可是,在编码上,各国”各自为政“,很难互相交流。因而出现了Unicode编码。Unicode是国际组织制定的能够容纳世界上全部文字和符号的字符编码方案。spa
Unicode规定字符最少使用2个字节表示,因此最少可以表示2**16=65536个字符。这样看来,问题彷佛解决了,各国人民都可以将本身的文字和符号加入Unicode,今后就能够轻松交流了。设计
然而,在当时,计算机的内存容量但是寸土寸金的状况下,美国等北美洲国家是不接受这个编码的。由于这凭空增长了他们文件的体积,进而影响了内存使用率,影响工做效率。这就尴尬了。
显然国际标准在美国这边不受待见,因此应运而生产生了utf-8编码。
UTF-8,是对Unicode编码的压缩和优化,它再也不要求最少使用2个字节,而是将全部的字符和符号进行分类:ASCII码中的内容用1个字节保存、欧洲的字符用2个字节保存,东亚的字符用3个字节保存。
这样,你们各取所需,皆大欢喜。
3、utf-8是如何节省存储空间和流量的
当计算机在工做时,内存中的数据一直是以Unicode的编码方式表示的,当数据要保存到磁盘或者网络传输时,才会使用utf-8编码进行操做。
在计算机中,”I'm 杰克"的unicode字符集是这样的编码表:
I 0x49 ' 0x27 m 0x6d 0x20 杰 0x6770 克 0x514b
每一个字符对应一个十六进制数(方便人们阅读,0x表明十六进制数),可是计算机只能读懂二进制数,因此,实际在计算机内表示以下:
I 0b1001001 ' 0b100111 m 0b1101101 0b100000 杰 0b110011101110000 克 0b101000101001011
因为Unicode规定,每一个字符最少占用2个字节,因此,以上字符串在内存中的实际占位以下:
I 00000000 01001001 ' 00000000 00100111 m 00000000 01101101 00000000 00100000 杰 01100111 01110000 克 01010001 01001011
这串字符总共占用了12个字节,可是对比中英文的二进制码,能够发现,英文的前9位都是0,很是的浪费空间和流量。
看看utf-8是怎么解决的:
I 01001001 ' 00100111 m 01101101 00100000 杰 11100110 10011101 10110000 克 11100101 10000101 10001011
utf-8用了10个字节,对比Unicode,少了2个字节。可是,咱们的程序中不多用到中文,若是咱们程序中90%的内容都是英文,那么能够节省45%的存储空间或者流量。
因此,在存储和传输时,大部分时候遵循utf-8编码
4、Python2.x与Python3.x中的编解码
1. 在Python2.x中,有两种字符串类型:str和unicode类型。str存bytes数据,unicode类型存unicode数据
由上图能够看出,str类型存储的是十六进制字节数据;unicode类型存储的是unicode数据。utf-8编码的中文占3个字节,unicode编码的中文占2个字节。
字节数据经常使用来存储和传输,unicode数据用来显示明文,那如何转换两种数据类型呢:
不管是utf-8仍是gbk都只是一种编码规则,一种把unicode数据编码成字节数据的规则,因此utf-8编码的字节必定要用utf-8的规则解码,不然就会出现乱码或者报错的状况。
python2.x编码的特点:
为何英文拼接成功了,而中文拼接就报错了?
这是由于在python2.x中,python解释器悄悄掩盖掉了 byte 到 unicode 的转换,只要数据所有是 ASCII 的话,全部的转换都是正确的,一旦一个非 ASCII 字符偷偷进入你的程序,那么默认的解码将会失效,从而形成 UnicodeDecodeError 的错误。python2.x编码让程序在处理 ASCII 的时候更加简单。你付出的代价就是在处理非 ASCII 的时候将会失败。
2. 在Python3.x中,也只有两种字符串类型:str和bytes类型。
str类型存unicode数据,bytse类型存bytes数据,与python2.x比只是换了一下名字而已。
还记得以前博文中提到的这句话吗?ALL IS UNICODE NOW
python3 renamed the unicode type to str ,the old str type has been replaced by bytes.
Python 3最重要的新特性大概要算是对文本和二进制数据做了更为清晰的区分,再也不会对bytes字节串进行自动解码。文本老是Unicode,由str类型表示,二进制数据则由bytes类型表示。Python 3不会以任意隐式的方式混用str和bytes,正是这使得二者的区分特别清晰。你不能拼接字符串和字节包,也没法在字节包里搜索字符串(反之亦然),也不能将字符串传入参数为字节包的函数(反之亦然)。
注意:不管python2,仍是python3,与明文直接对应的就是unicode数据,打印unicode数据就会显示相应的明文(包括英文和中文)
5、文件从磁盘到内存的编码
当咱们在编辑文本的时候,字符在内存对应的是unicode编码的,这是由于unicode覆盖范围最广,几乎全部字符均可以显示。可是,当咱们将文本等保存在磁盘时,数据是怎么变化的?
答案是经过某种编码方式编码的bytes字节串。好比utf-8,一种可变长编码,很好的节省了空间;固然还有历史产物的gbk编码等等。因而,在咱们的文本编辑器软件都有默认的保存文件的编码方式,好比utf-8,好比gbk。当咱们点击保存的时候,这些编辑软件已经"默默地"帮咱们作了编码工做。
那当咱们再打开这个文件时,软件又默默地给咱们作了解码的工做,将数据再解码成unicode,而后就能够呈现明文给用户了!因此,unicode是离用户更近的数据,bytes是离计算机更近的数据。
其实,python解释器也相似于一个文本编辑器,它也有本身默认的编码方式。python2.x默认ASCII码,python3.x默认的utf-8,能够经过以下方式查询:
import sys print(sys.getdefaultencoding())
若是咱们不想使用默认的解释器编码,就得须要用户在文件开头声明了。还记得咱们常常在python2.x中的声明吗?
#coding:utf-8
若是python2解释器去执行一个utf-8编码的文件,就会以默认的ASCII去解码utf-8,一旦程序中有中文,天然就解码错误了,因此咱们在文件开头位置声明 #coding:utf-8,其实就是告诉解释器,你不要以默认的编码方式去解码这个文件,而是以utf-8来解码。而python3的解释器由于默认utf-8编码,因此就方便不少了。
参考资料