恼人的 Python 编码
一、编码常识
ASCII:英文编码,存储长度 1 byte
Unicode:万国语言编码,未定义存储长度
ASCII 存储方便,表达力不行(只能表示英文),Unicode 表达能力强,存储浪费空间极大
UTF-8:Unicode 实现方法之一,存储长度 1~4 bytes
- 对于单字节的符号,字节的第一位设为
0
,后面7位为这个符号的 Unicode 码。对于英语字母,UTF-8 编码和 ASCII 码是相同的 - 对于
n
字节的符号(n > 1
),第一个字节的前n
位都设为1
,第n + 1
位设为0
,后面字节的前两位一律设为10
。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码
GBK:中文编码,存储长度 2 bytes
参考:阮一峰:字符编码笔记
二、string 的 encode、decode 逻辑
字符串在 python 的 str 里使用 Unicode 编码,编码转换时,通常需要用 unicode 作为中间编码,逻辑如下
如果需要传输这些字符,则需要进行字符编码,这时候需要将 str 进行编码,
三、python2,python3 对字符串处理的差异
1. 默认编码
首先解释一下默认编码,这个是 python 脚本默认使用的编码,主要影响的有:文件的读取、输入输出流的读取等,文件的读取在使用 open 的时候可以强制指定编码、解码格式,但是默认编码使用 ascii,输入输出一旦含有中文立刻锟斤拷。
python2 默认编码 ascii,python3 默认编码 utf-8,调用 sys.getdefaultencoding() 查看
这也是为什么 python2 中如果要写中文,需要指定默认编码的原因:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
不写这个会出现的结果就是。。。
2. 编码解码问题
这个问题非常恶心,首先要知道,Unicode 就是用来解码的,其他编码是用来编码的,把上面那张图办下来帮助理解:
python2
str 指 bytes(就是已经经过编码,而且是用默认的 ascii 编码),这个玩意儿还能 encode。。。没卵用,用了就报错。。。同样 unicode 有一个 decode,一用就报错,卵用没有,但是喜滋滋将 str 进行 decode 的时候,会出现下面结果
啊啊啊啊啊,这是为啥,原因 python2 会对于 Unicode 对象自动执行 ascii 编码转化为 str,执行 a.encode('utf-8')
相当于执行了 a.encode('ascii').decode('ascii')
,ascii 不支持中文,所以就会报错,因此使用 python2 时,大多中文字符串加上 u 前缀,统一编码为 utf-8
python3
str 就是指 unicode,如果想得到 bytes,就需要字符串加前缀 b(但字符串不能含中文),或者进行 encode,这样使用起来就非常清晰方便
总结
编码问题非常讨厌,报错报到头秃。。。在需要网络传输字符数据的时候尤为重要,如果使用爬虫啊,解析 http 包啊这类东西,搞不清楚编码能把人磕碜死(流下没技术的泪水)


原文链接:恼人的 Python 编码
nightmorning的博客 版权所有,转载请注明出处。
还没有任何评论,你来说两句吧!