最近在学习python的时候遇到了字符集的相关内容,感觉有点迷糊,写点笔记,查缺补漏一下
字符编码基本内容
计算机只认识二进制,所以生活中的各种进制的数字都必须转换为二进制才能让机器理解,而文字和数字没有关系,所以约定一张表,将文字和数字相对应上,这样就可以根据数字来找到对应的文字。
中国常用编码介绍一览表
编码 | 制定时间 | 作用 | 所占字节数 |
---|---|---|---|
ASCII | 1967年 | 表示英语及西欧语言 | 8bit/1bytes |
GB2312 | 1980年 | 国家简体中文字符集,兼容ASCII | 2bytes |
Unicode | 1991年 | 国际标准组织统一标准字符集 | 2[通常]-4bytes |
GBK | 1995年 | GB2312的扩展字符集,支持繁体字,兼容GB2312 | 2bytes |
UTF-8 | 1992年 | 不定长编码 | 1-3bytes[通常],4-6bytes |
部分字符集
ASCII
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码),是单字节编码系统,通常情况下前128个是ASCII编码,后128个称为扩展ASCII码,主要显示英语以及某些符号,如下图所示,是一张ASCII码表
图片引用百度百科
备注:在计算机中,1个字节定义为8位,用来解决‘断句’的问题,所以1个bit(比特)是最小的表示单位,一个字节是最小的存储单位
GB2312和GBK以及其他的地方编码
对于部分国家和地区来说,256个字符无法对应自己的所有文字,所以就制定了满足地方文字的编码集,比如,
中文编码(GBK,GB2312,GB18030)
韩文编码(ks_c_5601-1987)
日本编码(Shift_JIS)
泰文编码(TIS-620)
Unicode
每个国家都有自己的标准,那么在国际交流的时候会带来不便,除非你安装相应的编码集,所以,万国码-Unicode诞生了,Unicode把所有的文字都统一到一套编码里,涵盖了几乎全球所有的文字和二进制的对应关系,解决了乱码的问题。
Unicode一个字符用2-4个字节来表示,通常是两个字节就可以表述一个字符,并且现代操作系统和大多数编程语言都支持Unicode。但是对于纯英文的内容的话,使用Unicode编码将会比ASCII编码多出一倍的空间大小,在存储和传输上不太合适。
UTF-8
由于Unicode的瑕疵,所以出现了“可变长编码”的UTF(Unicode Transformation Format)-8编码,对Unicode的字符进行转换,以便在存储和网络传输时节省空间。
小结
理解了ASCII,Unicode和UTF-8,字符编码的工作方式:
在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者进行传输的时候,就转换为UTF-8编码。比如:用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后保存的时候,再把Unicode转换为UTF-8保存在文件中。
Python3和Python2的编码
Python3的解释器在将字符加载到内存中的时候会默认将字符集转成了Unicode,但是Python2却不会,你的文件编码声明是什么,加载到内存中就是什么编码,这意味着如果环境和声明的编码方式不一样,那么就算使用UTF-8,依然可能会出现乱码。
Python3的执行过程
- 解释器找到代码文件,把代码字符串按文件头(在python3中如果没有文件头定义编码方式,默认是UTF-8)定义的编码加载到内存,转成Unicode。
- 把代码字符串按照语法规则进行解释。
- 所有的变量字符都会以Unicode编码声明。
Python2的执行过程
既然Python3能将编码转成Unicode,那么可能是调用了decode(解码)
和encode(编码)
。
UTF-8/GBK... --> decode 解码 -->Unicode
Unicode --> encode 编码 --> UTF-8/GBK...
常见的编码错误原因
Python如果出现了编码问题,可以按照以下方面进行排查:
- Python解释器的默认编码
- Python源文件文件编码
- Terminal使用的编码
- 操作系统的语言设置