重庆市网站建设公司,英文网站有哪些,微商城小程序app开发,企鹅媒体平台字符/文本编码解码笔记1.字符问题编码和解码2.字节概要3.基本的编解码器编码类型史字符编码ASCII码GB2312以及其他编码UNICODE标准编码UTF-8编码4.了解编解码问题处理UnicodeEncoderError解决方法:处理UnicodeDecodeError解决方法5.修改源代码编码6.查看文件编码方式终端查看文…
字符/文本编码解码笔记1.字符问题编码和解码2.字节概要3.基本的编解码器编码类型史字符编码ASCII码GB2312以及其他编码UNICODE标准编码UTF-8编码4.了解编解码问题处理UnicodeEncoderError解决方法:处理UnicodeDecodeError解决方法5.修改源代码编码6.查看文件编码方式终端查看文件编码方式代码内查看文件编码方式7.处理文本文件查看open函数默认编码方式1.字符问题
“字符串”是个相当简单的概念一个字符串是一个字符序列。 在 2015 年“字符”的最佳定义是 Unicode 字符。因此从 Python 3 的 str 对象中获取的元素是 Unicode 字符。但是Python 3 默认使用 UTF-8 编码源码。注意区分。 Unicode 标准把字符的标识和具体的字节表述进行了如下的明确区分。
字符的标识即码位是 0~1 114 111 的数字十进制在 Unicode 标准中以 4~6 个十六进制数字表示而且加前缀“U”。例如字母 A 的码位是 U0041。字符的具体表述取决于所用的编码,也就是除了Unicode以外其他编码的表示。编码是在码位和字节序列之间转换时使用的算法。比如在 UTF-8 编码中AU0041的码位编码成单个字节 \x41。一个字符串则编码为由多个字节组成的字节序列。后面会多处提到字节序列把它当成用其他编码器对Unicode字符编码的结果就可以了。
编码和解码
编码是把码位转换成字节序列的过程。通俗的讲就是将Unicode编码的字符转化为其他编码的字符。 解码是把字节序列转换成码位的过程。通俗的讲就是将其他编码的字符转化为Unicode编码的字符。
ssabér
print(s)
print(len(s)) #1
bs.encode(utf-8) #2
print(b) #3
print(len(b)) #4
xb.decode(utf-8)#5
print(x) 输出
sabér
5
bsab\xc3\xa9r
6
sabér1.sabér字符串有5个Unicode字符。2.使用UTF-8把str对象编码成bytes对象。3.bytes字面量以b开头表示字节序列。4.字节序列 b 有 5 个字节在 UTF-8 中“é”的码位编码成两个字节。5.使用 UTF-8 把 bytes 对象(字节对象)解码成str 对象。
由于Unicode编码是标准编码格式也可以看做是没有任何特定编码格式的“无编码”模式。所以对于任何Unicode类型编码的字符打印时python会自动根据环境编码转为特定编码后再显示Python 3 为所有平台设置的默认编码都是 UTF-8。
2.字节概要
Python 内置了两种基本的二进制序列类型不可变 bytes 类型和 可变 bytearray 类型。
3.基本的编解码器
Python 自带了超过 100 种编解码器codec, encoder/decoder用于在文本和字节之间相 互转换。每个编解码器都有一个名称如 ‘utf_8’而且经常有几个别名如 ‘utf8’、‘utf-8’ 和 ‘U8’。
上图有12个字符code point表示其码位还有7种编码的字节表述(十六进制)。星号表明某些编码如 ASCII 和多字节的 GB2312不能表示所有 Unicode 字符。然而UTF 编码的设计目的就是处理每一个 Unicode 码位。
编码类型史
字符编码
将人类语言转化为计算机能够理解的二进制的数(0,1)我们用bit(位)来表示通常转化的时候是按byte(字节)来处理一个字节等于8bit。
ASCII码
ASCII码是人类计算机历史上最早发明的字符集ASCII码是专门为表示英文、数字以及英文标点符号而生。ASCII编码使用一个字节编码一个字节有256种组合足够存储这些字符。
GB2312以及其他编码
由于中文汉字非常多ASCII无法满足汉字存储的需求。 为了满足国内在计算机中使用汉字的需要中国国家标准总局发布了一系列的汉字字符集国家标准编码统称为GB码或国标码。 其中最有影响的是于1980年发布的《信息交换用汉字编码字符集 基本集》标准号为GB 2312-1980,因其使用非常普遍也常被通称为国标码。GB2312编码通行于我国内地新加坡等地也采用此编码。几乎所有的中文系统和国际化的软件都支持GB 2312。 所以大家可以理解为GB系列的编码是为了适应复杂的中文编码而对ASCII码的一种扩充。
UNICODE标准编码
每个国家都会对ASCII码扩展出自己的一套编码就存在不同编码之间的转换和显示问题。为了解决这个问题需要一套统一的编码格式即Unicode。 Unicode又被称为统一码、万国码它为每种语言中的每个字符设定了统一并且唯一的二进制编码以满足跨语言、跨平台进行文本转换、处理的要求。 Unicode编码通常由两个字节组成共表示256*256个字符即所谓的UCS-2。某些偏僻字还会用到四个字节即所谓的UCS-4。 并且Unicode兼容ASCII在Unicode中原本ASCII中的127个字符只需在前面补一个全零的字节即可。
UTF-8编码
UNICODE编码有个缺点所有语言的字符都是固定长度的存储有些语言的字符只需占用少量的存储空间这就导致浪费了大量的存储空间。 为了解决这个问题就出现了一些中间格式的字符集他们被称为通用转换格式即UTFUnicode Transformation Format。 我们最常用的UTF-8就是这些转换格式中的一种。UTF-8编码其实是一种可“变长”的编码格式即把英文变长为1个字节而汉字用3个字节表示特别生僻的还会变成4-6字节。
该部分参考一文搞懂Python字符编码问题
4.了解编解码问题
虽然有个一般性的 UnicodeError 异常但是报告错误时几乎都会指明具体的异常UnicodeEncodeError把字符串转换成二进制序列时或 UnicodeDecodeError把二进制序列转换成字符串时。如果源码的编码与预期不符 加载 Python 模块时还可能抛出 SyntaxError。
处理UnicodeEncoderError
多数非 UTF 编解码器只能处理 Unicode 字符的一小部分子集。把文本(Unicode 字符)转换成字节序列时如果目标编码中没有定义某个字符那就会抛出 UnicodeEncodeError 异常。
解决方法:
1.在encode()函数中添加参数error举例如下:
city São Paulo
xcity.encode(cp437, errorsignore)
print(x)
ycity.encode(cp437, errorsreplace)
print(y)
zcity.encode(cp437, errorsxmlcharrefreplace)
print(z)输出:
bSo Paulo
bS?o Paulo
bS#227;o Pauloerror‘ignore’ 处理方式悄无声息地跳过无法编码的字符 errorreplace’把无法编码的字符替换成 ‘?’ error‘xmlcharrefreplace’ 把无法编码的字符替换成 XML实体。 以上解决是十分不妥的损坏了数据。 编解码器的错误处理方式是可扩展的。你可以为 errors 参数注册额外的字符串方法是把一个名称和一个错误处理函数传给 codecs.register_error 函数。 参见 codecs.register_error 函数的官方文档。
2.换一种编码器尽量使用UTF-8编码器。
处理UnicodeDecodeError
ASCII字符有127个但是一个字节表示的空间有256个。所以不是每一个字节都包含有效的 ASCII 字符。 同理不是每一个字符序列都是有效的 UTF-8 或 UTF-16。 把二进制序列(字节序列)转换成文本(Unicode字符)时如果字节序列有无效的字节时遇到无法转换的字节序列时会抛出 UnicodeDecodeError。 举例如下:
octets bMontr\xe9al
octoctets.decode(cp1252)
print(oct)
oct1octets.decode(utf_8)
print(oct1)
oct2octets.decode(utf_8, errorsreplace)
print(oct2)输出
Montréal
Traceback (most recent call last):File c:\Users\13451\Desktop\python基本操作\1.py, line 18, in moduleoct1octets.decode(utf_8)
UnicodeDecodeError: utf-8 codec cant decode byte 0xe9 in position 5: invalid continuation byte
Montral这些字节序列是使用 latin1 编码的“Montréal”’\xe9’ 字节对应“é”。可以使用 ‘cp1252’Windows 1252解码因为它是 latin1 的有效超集。‘utf_8’ 编解码器检测到 octets 不是有效的 UTF-8 字符串抛出 UnicodeDecodeError。bug中position从零开始数。
解决方法
使用 ‘replace’ 错误处理方式\xe9 替换成了替换字符码位是 UFFFD这是官方指定的 REPLACEMENT CHARACTER替换字符表示未知字符。替换字符:形状为黑色菱形且中间填充了一个问号。
5.修改源代码编码
Python 3 默认使用 UTF-8 编码源码且Python 3 为所有平台设置的默认编码都是 UTF-8。 在源代码第一行加# coding: cp1252即可用cp1252编码或者编辑器或IDE都有更改编码的途径。
6.查看文件编码方式
终端查看文件编码方式
安装统一字符编码侦测包 Chardet。 终端使用:
chardetect 1.py输出:
1.py: utf-8 with confidence 0.99表示1.py有0.99的可能是utf-8编码。
代码内查看文件编码方式
使用chardet库的detect函数
import chardet
file1data/test.txt
fopen(file1,rb)
f_encodingchardet.detect(f.read())
print(f_encoding)
f.close()输出:
{encoding: utf-8, confidence: 0.99, language: }7.处理文本文件
使用open()函数打开文件,有两种方式处理文件:文本模式和二进制模式。 添加encoding参数可以设置编码方式这个编码方式在编码输出文本的时候会用到即下图第三行。open()函数默认采用文本模式。默认编码方式取决于平台window10下为gbklinux下为utf-8。当处于二进制模式时不能添加encoding参数因为本身就是二进制了不需要再编码。
如果调用read()函数open 函数会在读取文件时做必要的解码(自动解码成Unicode字符,即str)。对应下图解码输入的字节序列得到str对象。如果调用write()函数以文本模式写入文件时还会做必要的编码。参数为str对象。对应下图第三行生成字节序列(bytes)。
整个处理文本文件的过程如下图
查看open函数默认编码方式
file1data/test.txt
fpopen(file1,w)
print(fp)
fp.close()win10下输出
_io.TextIOWrapper namedata/test.txt modew encodingcp936cp936即 code page 936代码页936是以GBK国标扩展字符集为基础的编码。基本和GBK差不多。
关于编码默认值的最佳建议是别依赖默认值。如果遵从 Unicode 三明治的建议而且始终在程序中显式指定编码那将避免很多问题。 参考了流畅的python第四章。