ascii、unicode、utf-8、gbk简介

ascii

ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符,1bytes代表一个字符
知识点:8bit = 1bytes

Unicode

为了统一世界各国语言的不同,统一用2个bytes代表一个字符,特点:速度快,但浪费空间

utf-8

为了改变Unicode的这种缺点,规定一个英文字符用一个字节表示,一个中文字符用三个字节表示,特点:节省空间,速度慢

gbk

是中文的字符编码,用2个字节代表一个字符

python使用ascii、unicode、utf-8、gbk之前转换关系

知识点

  • Unicode编码可支持世界各国语言。
  • 在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8或GBK编码(bytes),可以节省空间。

Python的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes

python-ascii

Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符:

>>> ord('A')
65
>>> ord('中')
20013
>>> chr(66)
'B'
>>> chr(25991)
'文'

Python对**bytes类型的数据用带b前缀的单引号或双引号表示:**

x = b'ABC'

bytes的每个字符都只占用一个字节,只支持ascii字符

python-unicode

Unicode表示的str通过**encode()方法可以编码为指定的bytes**

知识点:

  • decode英文意思是 解码,encode英文原意 编码
  • 字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码, 即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。
  • decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode(‘gb2312’),表示将gb2312编码的字符串str1转换成unicode编码。
  • encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode(‘gb2312’),表示将unicode编码的字符串str2转换成gb2312编码。

如果字符需要在网络上传输或写入磁盘,可以进行对其进行编码:

>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
  • 纯英文的str可以用ASCII编码为bytes,内容是一样的,含有中文的str可以用UTF-8编码为bytes。
  • 在bytes中,无法显示为ASCII字符的字节,用\x##显示,而每个中文占3个bytes,所有"中文"编码为UTF-8后共有6个bytes保存。
  • 含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。

如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用**decode()**方法:

>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'

小贴士:

python转义字符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IruZgaiU-1640000999556)(.asset/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81%E7%9B%B8%E5%85%B3/20180309150228593)]

python 全局gbk编码 python中gbk_python

Python 3 的 surrogateescape

所以,日志里这个 surrogate 是个啥?

Surrogate 是 Unicode 中位于 BMP 外的一组不会有对应字符的码位,Python 3 中使用这些码位来「代表」无法编码的字节。

如果你明白「锟斤拷」是怎么来的,那么就一定能理解 Python 的 replace 编解码错误处理机制:无法解码的字节会被替换成 U+FFFD ,无法编码的码位会被替换成 ?。这样做有一个明显的缺点就是不可逆。Python 3 中新增的 surrogateescape 则是一种可逆的错误处理机制,利用 Surrogate 码位保存无法解码的字节,编码时则将其还原为对应的原始字节。

例子中的报错正是因为 0xE6 无法使用 ascii 解码,而被解为了 U+DCE6 。

'\udce6'.encode('ascii', 'surrogateescape')
>>> b'\xe6'
b'\xe6'.decode('ascii', 'surrogateescape')
>>> '\udce6'

参考:


https://www.zuimoban.com/jiaocheng/python/7667.html

https://docs.python.org/zh-cn/3/library/codecs.html