Python编码问题详解

当你在进行读写操作出现如下报错
UnicodeEncodeError: ‘utf-8’ codec can’t encode character ‘\u704f’ in position 0
或者乱码,那么看这篇文章是对的

什么是编码和解码

计算机只认识0或1组成的二进制数,而人类只认识文字,必须要有一个从文字到0,1的映射。从文字到0,1的映射称为编
码,反过来从0,1到文字叫解码

编码和解码常用在文件读写,数据传输过程。

编码方式有很多种,每个人都可以自己定义一套编码方式,缺点是无法通用。不知道编码方式,那么就无法解码,或者说解出来的是乱码

几种编码方式

1.ASCII

ASCII是美国国家标准学会制定的编码规则,将英文字符映射到一个二进制位。ASCII 码一共规定了128个字符的编码,比如空格SPACE是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的一位统一规定为0。

一个字符 = 一个字节

2.GBK,GB2312,GB18030

这三个是中文编码家族

GB2312 最早一版的中文编码,每个字占据2bytes。由于要和ASCII兼容,那这2bytes最高位不可以为0了(否则和ASCII会有冲突)。在GB2312中收录了6763个汉字以及682个特殊符号,已经囊括了生活中最常用的所有汉字。

GBK编码后,可以表示的汉字达到了20902个,另有984个汉语标点符号、部首等。每个字依然占2bytes

GB18030编码的中文文件已经有七万多个汉字了,甚至包含了少数民族文字。多出来的汉字用4bytes表示

兼容性关系是GB18030兼容GBK,GBK兼容GB2312,GB2312兼容ASCII

3.UNICODE和UTF-8

前面两个国家就有两套编码方式,还有欧洲,日韩等国使用的文字大相径庭,每个国家都制定一套代码的话,那么不同国家之间的网络交流着实困难。因此统一的一个编码规则应运而生,它就是unicode。Unicode收纳了全世界大部分的字符,所有的字符都有唯一的编码,解决了大家解码冲突。

可是,问题来了,当时绝大数的网络资源都是用英文存储的,而英文只占1个字符就够了,如果按照Unicode存储,将极大地浪费存储资源。

UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。其他实现方式还包括 UTF-16(字符用两个字节或四个字节表示)和 UTF-32(字符用四个字节表示)

UTF-8是一种变长的编码方式,他可以用1~4个字节表示一个符号。前面我们提到的编码方式ASCII是一个字符用一个字节表示,GBK是两个字节表示一个字符,都是固定的。

UTF-8 的编码规则很简单,只有二条:

对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。

对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

unicode符号范围 UTF-8编码方式
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。

>>> a = '水水'
>>> a.encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

>>> a.encode('gbk')
b'\xcb\xae\xcb\xae'

>>> a.encode('unicode_escape')
b'\\u6c34\\u6c34'

>>> a.encode('utf-8')
b'\xe6\xb0\xb4\xe6\xb0\xb4'
>>> 

计算机系统通用的字符编码工作方式

计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。

写入
读取
内存unicode
硬盘utf-8

python3中的encode和decode

Python编译器内部使用的时候使用unicode处理

encode 指的是将unicode编码转换成其他编码方式的字符串

decode是指将其他编码的字符串转换成unicode编码

这里强调一下读写文件时的encoding参数指的是读写文件时的编码方式。比如文件写入时,按照

未完待续…


参考文献

  1. 一图弄懂ASCII、GB2312、GBK、GB18030编码
  2. 底搞清楚ASCII,Unicode和UTF-8之间的关系
  3. utf-8和Unicode的区别
  4. 新手需要知道decode 和 encode 区别【转载】
  5. [吐血总结,彻底明白 python3 编码原理](https://blog.csdn.net/qq_33692803/article/details/81321340

你可能感兴趣的:(Python)