当前位置: 代码迷 >> 综合 >> Fluent Python - Part4 文本和字节序列
  详细解决方案

Fluent Python - Part4 文本和字节序列

热度:41   发布时间:2024-02-27 08:47:39.0

人类使用文本,计算机使用字节序列

--- Esther Nam 和 Travis Fischer

本章内容基本没啥用,平常也基本接触不到多编码类型的文本处理。所以这一章会写得有点简陋hhh。

字符问题

  • 把码位转换成字节序列的过程叫编码;把字节序列转换成码位的过程叫解码。换句话说,把人类看得懂的字符串转换成机器看得懂的序列的过程叫编码;反之叫解码。

了解编解码的问题

当编解码出现问题时,几乎都会指明具体的异常:UnicodeEncodeError(把字符串转换成二进制序列时)或 UnicodeDecodeError(把二进制序列转换成字符串时)

处理UnicodeEncodeError

  • 多数非 UTF 编解码器只能处理 Unicode 字符的一小部分子集。把文本转换成字节序列时,如果目标编码中没有定义某个字符,那么就会抛出 UnicodeEncodeError 异常,除非把 errors 参数传给编码方法或函数,对错误进行特殊处理。

一个例子

Python 3.6.9 (default, Apr 18 2020, 01:56:04)
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> city = 'S?o Paulo'
>>> city
'S?o Paulo'
>>> city.encode('cp437')
Traceback (most recent call last):File "<stdin>", line 1, in <module>File "/usr/lib/python3.6/encodings/cp437.py", line 12, in encodereturn codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character '\xe3' in position 1: character maps to <undefined>>>> city.encode('cp437', errors='ignore')
b'So Paulo'
>>> city.encode('cp437', errors='replace')
b'S?o Paulo'
>>> city.encode('cp437', errors='xmlcharrefreplace')
b'S&#227;o Paulo'

处理 UnicodeDecodeError

  • 不是每个字符都包含有效的 ASCII 字符,也不是每一个字符序列都是有效的 UTF-8 或 UTF-16。因此,把二进制序列转换成文本时,如果假设是这两个编码中的一个,遇到无法转换的字节序列时会抛出 UnicodeDecodeError
  • 另一方面,很多陈旧的8位编码,如’cp1252’, ‘iso8859_1’ 和 ‘koi8_r’。能解码任何字节任何字节序列流而不抛出错误,并且得到无用输出。

一个例子

>>> octets = b'Montr\xe9al'
>>> octets.decode('cp1252')
'Montréal'
>>> octets.decode('iso8859_7')
'Montrιal'
>>> octets.decode('koi8_r')
'MontrИal'
>>> octets.decode('utf-8')
Traceback (most recent call last):File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 5: invalid continuation byte
>>> octets.decode('utf-8', errors='replace')
'Montr?al'

哈哈哈,数据结构部分终于结束了,下一部分我们的重点是函数