when someone abandons you,it is him that gets loss because he lost someone who truly loves him but you just lost one who doesn’t love you.
无论是 py2 还是 py3 都可以理解成是 Unicode 编码,但是在电脑硬盘上存储是按照不同的映射关系的
首先需要清楚的是 python 的 encode 和 decode,在搞清楚这个问题之前,还得知道 Unicode 将所有的字符都对应了相应的码点,而 UTF-8 或者 ASCII 码是对应从 Unicode 到字节的映射方式,既然有映射方式,就有映射方向,从 Unicode 到字节码(byte string)叫 encode,把从字节码(byte string)到 Unicode 码叫 decode。感觉还是不清晰,再普及几个 “字” 字辈的兄弟
字节
字节(Byte)是计算机中数据存储的基本单元,一字节等于一个 8 位的比特,计算机中的所有数据,不论是保存在磁盘文件上的还是网络上传输的数据(文字、图片、视频、音频文件)都是由字节组成的
字符
这篇文章就是由很多个字符(Character)构成的,字符一个信息单位,它是各种文字和符号的统称,比如一个英文字母是一个字符,一个汉字是一个字符,一个标点符号也是一个字符
字符集
字符集(Character Set)就是某个范围内字符的集合,不同的字符集规定了字符的个数,比如 ASCII 字符集总共有128个字符,包含了英文字母、阿拉伯数字、标点符号和控制符。而 GB2312 字符集定义了 7445 个字符,包含了绝大部分汉字字符
字符码
字符码(Code Point)指的是字符集中每个字符的数字编号,例如 ASCII 字符集用 0-127 连续的 128 个数字分别表示 128 个字符,例如 “A” 的字符码编号就是 65
字符编码
字符编码(Character Encoding)是将字符集中的字符码映射为字节流的一种具体实现方案,常见的字符编码有 ASCII 编码、UTF-8 编码、GBK 编码等。某种意义上来说,字符集与字符编码有种对应关系,例如 ASCII 字符集对应 有 ASCII 编码。ASCII 字符编码规定使用单字节中低位的 7 个比特去编码所有的字符。例如 “A” 的编号是 65,用单字节表示就是 0×41,因此写入存储设备的时候就是 b’01000001’
编码、解码
编码的过程是将字符转换成字节流,解码的过程是将字节流解析为字符
python2 中,有两种不同的字符串数据类型:
str 对象,字节存储
在字符串前使用一个 ’u’ 的前缀,表示的是这个字符的 Unicode 码点
Python2 处理英文字符
1 | str='hello' # 首先 ’hello' 字符串的每个英文字符变换成 unicode 编码,在存储时 python2 对英文按照 ascii 映射的方式编码存储 5 个字节编码 |
Python2 处理中文字符
1 | # 直接输入 |
1 | u'字符串输入' |
Python2 开头为啥写 #coding=utf-8
Python 文件编译最终还是要转换成字节码,Python2 开头写 #coding=utf-8 其实就是把这个 Python 文件按照 utf-8 编码的方式映射到字节码,如果不加这个开头,代码里面的中文会按照 Python 默认的 ascii 码方式 encode。加了这个开头之后,程序里面的字符都将会使用 utf-8 编码的方式被映射到字节码,也就是上一个大节里面的 byte string,值得注意的是,程序中的汉字将会以 utf-8 的形式编码成为字节码,因此如果需要将其 decode 到 Unicode 字符,也是需要使用 utf-8 方式 decode
但是,这个开头并没有改变 Python 的系统编码方式:Python2 默认的编码解码方式是 ascii
1 | # 错误的 test.py |
1 | $ python test.py |
修复这个问题的方法有下面两种
1 | import sys |
1 | # 正确的 test.py |
1 | $ python test.py |
Python 3 也有两种类型,一个是 str(unicode), 一个是 byte 码
Python 3 中对 Unicode 支持的最大变化就是没有对 byte 字符串的自动解码
如果你想要用一个 byte 字符串和一个 unicode 相连接的话,你会得到一个错误,不管包含的内容是什么。可以简单理解为: python2 中的 unicode -> python3 的 str,python2 中的 str -> python3 的 byte
python3 处理中文
1 | >>> s="中" |
对于 byte 字节
二进制形式输出:不加 b,乱码;加 b,当字符串输出
用变量存储输出:二进制输出
对于 unicode(str)
直接输出汉字/英文
1 | print('\xe4\xb8\xad') # utf-8 |
python3 处理英文字符
1 | s='dv' |
ASCII 编码
最早出现的是 ASCII 码,使用 8 位二进制数组合表示 128 种字符。因为 ASCII 编码是美国人发明的,当初没考虑给别的国家用,所以,它仅仅表示了所有美式英语的语言字符。但是没有使用完
ISO 8859-1/windows-1252
128 位字符满足了美国人的需求,但是随之欧洲人加入互联网,为了满足欧洲人的需求,8 位二进制后面还有 128 位。这一段编码称之扩展字符集,即 ISO 8859-1 编码标准,后来欧洲的需求变更,即规定了 windows-1252 代替了 ISO 8859-1
GB2312
当我国加入后,8 位二进制(即一个字节)用完了,于是保留 ASCII 编码即前 128 位,后面的全部删除。因为我国的语言博大精深,所以需要 2 个字节,即 16 位才能满足需求,所以当计算机遇到大于 127 的字节时,就一次性读取两个字节,解码成汉字。即 GB2312 编码
GBK
相当于 GB2312 的改进版,增添了中文字符。但还是 2 个字节表示汉字
GB18030
为了满足日韩和我国的少数民族的需求,对 GBK 的改进,使用变长编码,要么使用两个字节,要么使用四个字节
Unicode
虽然每种编码都兼容 ASCII 编码,但是各个国家是不兼容的。于是出现了 Unicode,它将所有的编码进行了统一。它不能算是一种具体的编码标准,只是将全世界的字符进行了编号,并没有指定他们具体在计算机中以什么样的形式存储。它的具体实现有UTF-8、UTF-16、UTF-32等
be slow to promise and quick to perform.