python运行时出现UnicodeDecodeError,UnicodeEncodeError错误时,应该如何去面对,解决。计算机处理文本时必须先转换为数字。计算机采用二进制。
字符串编码
(1)通用的unicode
(2)将unicode编码转换为某种类型的编码
字节
数据存储基本单元,一字节等于8bit,所以一个字节对应256种状态。
字符
字符一个信息单位,它是各种文字和符号的统称,比如一个英文字母是一个字符,一个汉字是一个字符,一个标点符号也是一个字符
字符集
个范围内字符的集合,不同的字符集规定了字符的个数。ASCII 字符集总共有128个字符,包含了英文字母、阿拉伯数字、标点符号和控制符。GB2312 字符集定义了7445个字符,包含了绝大部分汉字字符
字符码
将字符集中的字符码映射为字节流的一种具体实现方案,常见的字符编码有 ASCII 编码、UTF-8 编码、GBK 编码
字符集与字符编码有种对应关系,
例如 ASCII 字符集对应 有 ASCII 编码。ASCII 字符编码规定使用单字节中低位的7个比特去编码所有的字符。例如"A" 的编号是65,用单字节表示就是0×41,因此写入存储设备的时候就是b'01000001'。
编码、解码
编码的过程是将字符转换成字节流,解码的过程是将字节流解析为字符。
ASCII 编码
为对应英文字符和二进制的关系,128字符编码
GB2312
中文常见编码方式,两字节表示一个汉字 理论有256x256=65536个符号
Unicode 统一码,万国码,单一码
能够跨语言 跨平台进行文本转换与处理
unicode编码两个字节,Ascii一个字节
A的ASCII编码:01000001 ,Unicode编码:0000000001000001 存储起来浪费空间,比ascii浪费一倍多,为节省空间 之间格式字符集,utf-8和utf-16
UTF
变长的字符编码,1-4个字节来表示一个字符,英文字母被编译为一个字节,汉字3个字节。
UTF-8的编码规则:
a.对于单字节符号,字节第一位设置为0,后面7位为这个字节的unicode编码,英文字母utf-8和ascii码是相同的
b.对于n字节符号(n>1) 第一个字节的前n位都设置为1,第n+1位设置为0,后面字节的前两位一律设置为10剩下的没有提及的二进制位全部为这个符号的unicode编码
编码对照案例:
在py3中 字符串编码使用str和bytes
(1)str字符串:使用Unicode编码
(2)bytes字符串:将unicode编码转换为某种类型的编码如utf-8
python3中默认编码unicode
encode和decode
encode 负责将unicode 编码成指定的字符编码
decode将其他字符编码转换为unicode编码
UnicodeEncodeError 和 UnicodeDecodeError 错误的原因
UnicodeEncodeError 和 UnicodeDecodeError 错误了,这些错误的根本原因在于 Python2 默认是使用 ascii 编码进行 decode 和 encode 操作
>> s = '我们'
>> s.decode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
当把 s 转换成 unicode 类型的字符串时,decode 方法默认使用 ascii 编码进行解码,而 ascii 字符集中根本就没有中文字符『你好』,所以就出现了 UnicodeDecodeError,正确的方式是显示地指定 UTF-8 字符编码。
>> s.decode('utf-8')
u'\u4f60\u597d'
对于 encode 操作,把 unicode字符串转换成 str类型的字符串时,默认也是使用 ascii 编码进行编码转换的,而 ascii 字符集找不到中文字符『你好』,于是就出现了UnicodeEncodeError 错误。
>> a = u'我们'
>> a.encode()
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 类型与 unicode 类型的字符串混合使用时,str 类型的字符串会隐式地将 str 转换成 unicode字符串,如果 str字符串是中文字符,那么就会出现UnicodeDecodeError 错误,因为 python2 默认会使用 ascii 编码来进行 decode 操作。
>> s = '你好' # str类型
>> y = u'python' # unicode类型
>> s + y # 隐式转换,即 s.decode('ascii') + u
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
正确地方式是显示地指定 UTF-8 字符编码进行解码
>> s.decode('utf-8') +y
u'\u4f60\u597dpython'
所有出现乱码的原因都可以归结为字符经过不同编码解码在编码的过程中使用的编码格式不一致