Python3的编码解码
梳理一下编码方面的知识点。
一、字符编码发展史
1、ASCII
背景:计算机设计8个比特(bit)作为一个字节(byte),即 1 字节对应 8 位二进制数,而每位二进制数有 0、1两种状态,因此 1 字节可以组合出 256 种状态。由此,美国设计出ASCII编码字典,英文字母和一些符号对应这些8位二进制数。
说明:1个字节代表一个字符。
例如:A 的编码为 65(对应二进制是0100 0001)。
问题:汉字超出了ASCII编码的范围。
2、GBK
背景:中国定制了GBK。
说明:2个字节代表一个字符(汉字),即可表达256*256=65536种字符。
问题:其他国家纷纷定制了自己的编码。
3、Unicode
背景:为表达任意语言的任意字符而设计出Unicode编码。
说明:所有的字符和符号最少由2个字节来表示。
问题:Unicode统一了各国编码,但对于英文则浪费了存储空间。
其他:
- 优点是字符转换为数字的速度快,但占用空间大
- 由于程序需要加载到内存才能使用,因此内存中使用的编码为Unicode,即用空间换时间。
4、UTF-8
背景:对Unicode编码进行压缩和优化,遵循能用最少的表示就用最少的表示。
说明:将所有的字符和符号进行分类,ASCII 码中的内容用 1 个字节保存、欧洲的字符用 2 个字节保存,东亚的字符用3个字节保存,包括中文,一些不常用的字符用四个字节表示。
其他:
- 优点是精准,对不同的字符用不同的长度表示,节省了空间,缺点是字符转换为数字的速度慢,因为每次都需要计算出字符需要多长的 Bytes 才能准确表示。
- 网络 I/O 延迟或磁盘 I/O 延迟要远大于 UTF-8 的转换延迟,且 I/O 应该尽可能节省带宽,保证数据传输的稳定性(数据传输追求稳定、高效,数据量越小数据传输越靠谱),因此保存到硬盘或网络传输采用 UTF-8。
5、Unicode 和 UTF-8 实际应用示例:
二、Python3 编码解码说明
背景:Python 对 bytes 类型的数据用带 b 前缀的单引号或双引号表示。如 ‘ABC’ 和 b’ABC’ ,前者是 str类型 ,后者为 bytes 类型。
说明:
- python3 中的字符串(str)为 Unicode, 只能encode(编码)。
1、编码
- 纯英文的 str 可以编码为bytes,内容是一样的:
str_1 = 'ABC'
print('字符串本身: ', str_1)
print('ASCII编码: ', str_1.encode('ascii'))
print('unicode_escape编码:', str_1.encode('unicode_escape'))
print('utf-8编码: ', str_1.encode('utf-8'))
print('gbk编码: ', str_1.encode('gbk'))
补充:在python中,unicode是内存编码集。将数据存储到文件时,需要将数据先编码为其他编码集,如 utf-8、gbk 等。读取数据时再通过同样的编码集进行解码即可。unicode-escape编码集是将unicode内存编码值直接存储。
- 中文的 str 可以用编码为bytes:
str_2 = '中文'
print('字符串本身: ', str_2)
print('unicode_escape编码:', str_2.encode('unicode_escape'))
print('utf-8编码: ', str_2.encode('utf-8'))
print('gbk编码: ', str_2.encode('gbk'))
注意:含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。
2、解码
str_3 = b'ABC'
print('ASCII解码: ', str_3.decode('ascii'))
print('unicode_escape解码:', str_3.decode('unicode_escape'))
print('utf-8解码: ', str_3.decode('utf-8'))
print('gbk解码: ', str_3.decode('gbk'))
str_4 = b'\\u4e2d\\u6587'
print('unicode_escape解码:', str_4.decode('unicode_escape'))
str_5 = b'\xe4\xb8\xad\xe6\x96\x87'
print('utf-8解码: ', str_5.decode('utf-8'))
str_6 = b'\xd6\xd0\xce\xc4'
print('gbk解码: ', str_6.decode('gbk'))
三、编码转换
1、GBK 转换 UTF-8
思想:
示例:
str_1 = b'\xd6\xd0\xce\xc4'
print('“中文”的GBK编码: ', str_1)
str_2 = str_1.decode('gbk')
print('第一步:用GBK解码: ', str_2)
str_3 = str_2.encode('utf-8')
print('第二步:用UTF-8编码:', str_3)
2、扩展
参考资料:
Python3之字符编码
python的编码问题