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 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'
参考: