Python进阶13_字符编码器

字符编码器

常见的编码器

Python 自带了超过 100 种编解码器(codec,encoder/decoder),用于在文本和字节之间相互转换。 例如:‘utf_8’,‘utf_16’…

需要设置编码器参数的主要用于如下函数:

  • open()
  • str.encode()
  • bytes.decode()

如下实例:

# 不同的编码的格式
for codec in ['latin_1','utf-8','utf-16']:
    print(codec,'El Niño'.encode(codec),sep='\t')
latin_1	b'El Ni\xf1o'
utf-8	b'El Ni\xc3\xb1o'
utf-16	b'\xff\xfeE\x00l\x00 \x00N\x00i\x00\xf1\x00o\x00'
主要的编码格式如下
  • latin1(即 iso8859_1):一 种 重 要 的 编 码, 是 其 他 编 码 的 基 础,
  • cp1252: Microsoft 制定的 latin1 超集,添加了有用的符号
  • cp437:IBM PC 最初的字符集,包含框图符号。
  • gb2312:用于编码简体中文的陈旧标准
  • utf-8:目前 Web 中最常见的 8 位编码
  • utf-16le:UTF-16 的 16 位编码方案的一种形式;所有 UTF-16 支持通过转义序列

编解码问题处理

  • 处理UnicodeEncodeError
    • 目标编码中没有定义某个字符
  • 处理UnicodeDecodeError
    • 遇到无法转换的字节序列

处理UnicodeEncodeError

多数非 UTF 编解码器只能处理 Unicode 字符的一小部分子集。把文本转换成字节序列时,如果目标编码中没有定义某个字符,那就会抛出UnicodeEncodeError 异常,

city ='São Paulo' 
print(city.encode('utf_8'))
print(city.encode('utf_16'))
print(city.encode('iso8859_1'))
# cp437无法处理ã,会报错误UnicodeEncodeError
# 'charmap' codec can't encode character'\xe3'
# print(city.encode('cp437'))

# 处理如下:跳过无法编码的字符
print(city.encode('cp437',errors='ignore'))

# 处理如下:把无法编码的字符替换成 '?'
print(city.encode('cp437',errors='replace'))

# 处理如下:无法编码的字符替换成 XML 实体
print(city.encode('cp437',errors='xmlcharrefreplace'))


b'S\xc3\xa3o Paulo'
b'\xff\xfeS\x00\xe3\x00o\x00 \x00P\x00a\x00u\x00l\x00o\x00'
b'S\xe3o Paulo'
b'So Paulo'
b'S?o Paulo'
b'São Paulo'

处理UnicodeDecodeError

不是每一个字节都包含有效的 ASCII 字符,也不是每一个字符序列都是有效的 UTF-8 或UTF-16。因此,把二进制序列转换成文本时,如果假设是这两个编码中的一个,遇到无法转换的字节序列时会抛出 UnicodeDecodeError。

octets = b'Montr\xe9al'

print(octets.decode('cp1252'))
print(octets.decode('iso8859_7'))
print(octets.decode('koi8_r'))

# 'utf-8' codec can't decode byte 0xe9
# 无法解码:抛出 UnicodeDecodeError
#print(octets.decode('utf_8'))

# \xe9 替换成了“�”
print(octets.decode('utf_8',errors='replace'))
Montréal
Montrιal
MontrИal
Montr�al

编码加载模块时抛出的SyntaxError

Python 3 默认使用 UTF-8 编码源码,Python 2(从 2.5 开始)则默认使用 ASCII.如果加载的 .py 模块中包含 UTF-8 之外的数据,而且没有声明编码.加载模块时抛出的SyntaxError.

#编码加载模块时抛出的SyntaxError的处理
# coding: cp1252
print('Olá, Mundo!')
print("瓦力人工智能")
Olá, Mundo!
瓦力人工智能

字节序列的编码的查找

如果所给的字节序列没有明确说明,是不能找到该字节序列是采用何种编码格式。但是我们可以根据里面的一下细节来试探和分析找出器编码格式。

可以采用统一字符编码侦测包 Chardet
识别所支持的 30 种编码。Chardet 是一个 Python 库,可以在程序中使用,不过它也提供了命令行工具 chardetect。

BOM:有用的字序节标记

UTF-16 编码的序列开头有几个额外的字节b'\xff\xfe\xe6t\x9bR\xbaN\xe5]zf\xfd\x80'

里面出现的b'\xff\xfe 就是 BOM(byte-order mark)字节序标记.这里表明:我编码的时候使用的是Intel CPU的小字节序.

Windows 应用(尤其是 Notepad)依然会在 UTF-8 编码的文
件中添加 BOM,UTF-8 编码的 U+FEFF 字符是一个三字节序列:b'\xef\xbb\xbf'

u16 = '瓦力人工智能'.encode('utf_16')
print(u16)
print(list(u16))
b'\xff\xfe\xe6t\x9bR\xbaN\xe5]zf\xfd\x80'
[255, 254, 230, 116, 155, 82, 186, 78, 229, 93, 122, 102, 253, 128]

分享关于人工智能,机器学习,深度学习以及计算机视觉的好文章,同时自己对于这个领域学习心得笔记。想要一起深入学习人工智能的小伙伴一起结伴学习吧!扫码上车!

瓦力人工智能 - 扫码上车

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值