【工程类】【Python】一文搞懂Python字符编码问题

Python的字符编码很是让人头疼,动不动就出现encode和decode ERROR的这些问题,,鉴于此,准备好好研究一番字符编码的问题,整理成文章。后续也会根据所学继续加入自己的理解。由于本人并非大神,如有讲错之处也请各位大神指出。

1、一些专有名词解释

字节
字节是计算机存储数据的基本单元,由8个bit组成。1024个字节就是1KB。
字符
字符是信息的基本单位,比如一个字母A,一个汉字‘好’,一个标点符号等,都可以称之为字符。
字符集
顾名思义,字符集就是字符的集合,比如全部的英文字母及其标点符号组成的集合(ASCII),比如全部中文字符及相应的标点符号组成的集合(GBK)
字符码 字符编码
字符码就是一个字符在字符集中所对应的编码,由于计算机只能识别ibt,所以对于一个字符来说,可以将这个字符表示为计算机可以识别的编码。比如字母‘a’,在ASCII中代表的字符码是97,其字符编码是0110 0001
编码 解码
编码的过程就是将字符转化为字节流。
解码的过程就是讲字节流转化为字符。

2、字符编码的历史

如果想要研究一个东西,那么我们就要知道这个东西的起源及历史原因。

2.1 ASCII编码

我们都知道,计算机这玩意最早是美国的,所以美国针对自己的语言设立了一套编码,这就是ASCII编码。由于英文字母有限,加上各种特殊字符之类的,总共凑了127个,所以完全可以用一个字节来表示,下图是ASCII表的表示。
在这里插入图片描述

2.2 MBCS编码

但是随着计算机的发展,更多国家接入了计算机,所以传统的ASCII码不能很好地表示不同国家的语言了。每个国家便推出了自己国家的编码规则,在兼容ASCII码的同时,又加入了自己的编码规则,由于ASCII编码是单字节,不能满足更多语言,所以一般会用双字节编码。
注意:MBCS不是一种编码,而是所有双字节编码的总称

2.2.1 GBK

咱们中国人在1981年也颁布了自己的中文编码,GB2312,GB2312 编码共收录了6763个汉字,同时他还兼容 ASCII,GB 2312的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆99.75%的使用频率,不过 GB2312 还是不能100%满足中国汉字的需求,对一些罕见的字和繁体字 GB2312 没法处理,后来就在GB2312的基础上创建了一种叫 GBK 的编码,GBK 不仅收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。同样 GBK 也是兼容 ASCII 编码的,对于英文字符用1个字节来表示,汉字用两个字节来标识。
在这里插入图片描述
可以看到,GBK和GB2312对于‘好’这个字的编码相同,且占两个字节。

2.3 unicode

虽然各个国家开发了自己国家的编码极大的解决了ASCII编码单字节的局限性,但是当各个国家之间的编码进行交互的时候又出现了问题,不同规则的编码在编码解码的过程中很容易出现乱码,且不容易维护。所以,unicode应运而生。
unicode是一种字符编码的统一,大家想出了一种策略,我们就用两个字节来表示,这就是UCS-2,不过后来大家发现256*256的空间同样不够了,就用4个字节来代替,这就是UCS-4。
unicode这种编码格式其实就是一种映射关系,将每一个字符映射到唯一的一个位上。

2.4 UTF-8

Unicode可以有效的解决了编码问题,不过老美们用了一段时间就不干了,我们自己的语言用一个字节就可以了,为啥还要用2个或者4个字节,太浪费空间了,所以老美们想出来一种字符编码UTF-8。那UTF-8是咋回事呢?这个是一种边长的字符编码。
对于一串序列来说首先判断第一位如果是0,则是单字节,11则是双字节,以此类推,其中后一个字节前两位均用10来表示。
在这里插入图片描述

3、Python2.X中的字符编码问题

终于到我们的重头戏了。
首先可以用一张图来一目了然的了解Python中的字符编码问题
在这里插入图片描述
解释一下:在Python中,str和unicode都继承basestring,str我们可以理解为一个字节数组,这点非常重要,比如用utf-8编码为XXX,在str中就是[‘XXX’],如果说用GBK编码为AAA,则在str中就是[‘AAA’].

3.1 如何用encode和decode进行str和unicode类型间的转换

在这里插入图片描述

4、Python执行流程解析

4.1执行流程

step1 根据文件编码将文件提交给解释器
step2 根据编码声明对文件进行逐行处理
step3 对于有打印到屏幕上的中文字符按sys.stdout.encoding进行编码
文件编码:文件是什么编码就是什么编码
编码声明:

#-*-coding:utf-8

打印编码:一般是根据操作系统进行设置

4.2举例说明

case1:文件编码GBK,系统编码GBK

print "你好"

报错:SyntaxError: Non-ASCII character '\xd5' in file /Users/leishuo/PycharmProjects/first/a.py on line 4, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
原因:step1:首先会根据文件编码将"你好"编译成“’\xc4\xe3\xba\xc3’”
step2:由于没有文件声明,所以会用默认ACSII码进行处理,由于ASCII无法处理“’\xc4\xe3\xba\xc3’”,所以报错。
case2:文件编码GBK,系统编码GBK

#-*-coding:utf-8
print "你好"

可能会报错
原因:由于有些高级编译器会根据文件声明自动将文件编码转化为文件声明编码。
如果进行转化:step1 将文件转化为utf-8编码。此时“你好”编码为"\xe4\xbd\xa0\xe5\xa5\xbd"
step2 根据文件声明进行处理。
step3 根据系统编码输出结果。

参考:

https://www.jianshu.com/p/53bb448fe85b
http://www.cnblogs.com/xsmhero/archive/2012/11/20/2778857.html
http://blog.sina.com.cn/s/blog_9f447dfd0102wp55.html##1
http://sa.sogou.com/sgsearch/sgs_tc_news.php?req=itzlnVR0ZmG7epVZiQ_9gYkn8bX_OL3UUkhQTWY37VAIQccfkBS8PHtXJWcymRa_&user_type=1
https://www.jb51.net/article/26543.htm
https://blog.csdn.net/ggggiqnypgjg/article/details/53271541

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章