User:Xyy23330121/Python/字符串和编码
本章将学习编码的相关信息,以及如何用 Python 生成或解决一类常见的文本乱码。
编码是计算机存储信息的方式。
bytes 对象是 Python 用于表示二进制数据的对象。我们可以用b
作前缀创建 bytes 对象:
a = b"abc"
此时,引号内的内容只能为 ASCII 编码中的字符。a
、b
和c
在 ASCII 编码中分别对应十六进制的61、62和63。所以上述例子中创建的对象,它所存储的二进制数据,用十六进制表示为 616263
。
由于 ASCII 编码仅有 127 个字符。因此,二进制每 8 位中,任何超出 127(即二进制的 01111111 ,或十六进制 7F )的二进制数值都需要通过转义字符来输入。比如:
a = b"\xf1"
上述例子中创建的对象,所存储的二进制数据,用十六进制表示为 f1
。
以上创建 bytes 对象的方法,也是用print
函数输出时的输出方式。有以下示例:
a = b"a\xf1b"
print(a) #输出:b'a\xf1b'
bytes 对象支持一切不可变序列的操作。虽然 bytes 的创建和表示方法是基于 ASCII 字符的,但比起 ASCII 字符构成的字符串,bytes 对象更像是 0~255 之间整数构成的元组。如果对 bytes 对象用整数索引,会返回一个整数,而非像字符串一样返回子字符串。
上面提到过,bytes 对象的表现类似由 0~255 之间整数组成的不可变序列。而 bytearray 对象类似由 0~255 之间整数组成的可变序列。bytearray 支持一切可变序列的操作。
类似 int 函数,我们可以用 bytes([source]) 和 bytearray([source]) 创建 bytes 对象或 bytearray 对象。
其中,参数 source 可以为整数、由 0~255 之间整数组成的可迭代对象。特别的,bytes 对象和 bytearray 对象也是由 0~255 之间整数组成的可迭代对象。
- 如果 source 为整数,则生成一个包含 source 个字节的对应实例。
- 如果 source 为由0~255之间整数组成的可迭代对象,则将可迭代对象中的整数原封不动复制到对应位置。
bytes.fromhex 方法和 bytearray.fromhex 方法可以用表示十六进制数字的字符串创建 bytes 对象,创建时字符串不区分大小写,并且会忽略空格。比如:
value = bytes.fromhex("81f0 EA61")
print(value) #输出:b'\x81\xf0\xeaa'
代码的输出说明,该 bytes 对象所存储的二进制数据,用十六进制表示为 81F0EA61
。
类似,我们还可以用 bytes.hex([sep[, bytes_per_sep]]) 或 bytearray.hex([sep[, bytes_per_sep]]) 方法创建十六进制字符串。
其中,sep 代表分隔符,默认为空字符串,即不插入分隔符。而 bytes_per_sep 代表插入分隔符的频率,默认为 1 ,即“每一个字节都插入一个分隔符”。我们有以下示例:
value = bytes.fromhex("81f0 EA61")
print(value.hex()) #输出:81f0ea61
print(value.hex(" ")) #输出:81 f0 ea 61
print(value.hex(" ",2)) #输出:81f0 ea61
bytes 和 bytearray 有类似字符串的方法。参见:U:Xyy23330121/Python/bytes 和 bytearray 的方法
编码名 | 适用语言 |
---|---|
utf-8 | 所有语言 |
ascii | 英语 |
big5 | 中文(繁体) |
gbk | 中文 |
shift-jis | 日语 |
utf-16 | 所有语言 |
utf-16-be | 所有语言 |
utf-16-le | 所有语言 |
utf-32 | 所有语言 |
utf-32-be | 所有语言 |
utf-32-le | 所有语言 |
字符编码 是将字符转化成二进制数据的标准。比如 &
字符,它在 ASCII 编码方式下,对应的二进制数据是 00100110
。计算机可以通过读取二进制数据,来还原出对应的字符串。常见的编码方式有 UTF-8、ASCII、UTF-16、GBK 等。
利用以下方法,我们可以把字符按编码转化成对应的bytes对象,也可以把bytes对象按编码转化成对应的字符对象。
str.encode(encoding='utf-8', errors='strict')
bytes.decode(encoding='utf-8', errors='strict')
其中,encoding
表示要使用的编码,此处不区分大小写,也不区分_
和-
。而errors
表示出错时的处理方法。右表列出了几种常用编码。如果要查阅所有可用的编码名称,可以参照上面列出的文档。
以下列出几种常用的错误处理方法。如果要查阅所有可用的方法,可以参照上面列出的“错误处理方式列表”文档。
名称 | 说明 |
---|---|
strict | 严格模式,遇到无法解码的码位或无法编码的字符,会报错 ValueError 。 |
ignore | 忽略错误。对于无法解码的码位或无法编码的字符,会直接跳过。 |
replace | 在编码时,遇到无法编码的字符,就用字符 ? 代替;在解码时,遇到无法解码的字节,就用字符 � (U+FFFD)代替。
|
现在绝大多数计算机,在信息处理时,都默认使用了 UTF-8 等常见的编码方式。但日本的计算机不一样,一些计算机有概率在处理信息时依旧使用 Shift-JIS 编码。中文计算机在解压zip压缩文件、查阅文本文档时,如果判断文件名或文本不是 UTF-8 编码,就会自动采用 GBK 编码来解码文件。用 Shift-JIS 编码的信息被用 GBK 解码就会导致乱码。
要解决这个问题,只需要结合上面的两个操作即可。我们用以下方式解决它:
error_str = "傕傕偄傠僇儖僥僢僩 搷壺"
print(error_str.encode("GBK").decode(encoding="Shift-JIS",errors="ignore"))
我们上面提到过 bytes 函数和 bytearray 函数。这两个函数的完整语法为:
bytes([source[, encoding[, errors]]])
bytearray([source[, encoding[, errors]]])
只有当 source 为字符串时,encoding 参数和 errors 参数才有作用,此时 bytes(source, encoding, errors)
等同于 source.encode(encoding, errors)
,而 bytearray(source, encoding, errors)
等同于 bytearray(source.encode(encoding, errors))
。