python3 在内存中是用 unicode 编码方式存储的, 所以不能直接储存和传输, 要转化为其他编码进行储存和传输.
字符串通过编码转换成字节码, 字节码通过解码成为字符串
- encode:str --> bytes
- decode:bytes --> str
下面是一些编码的关系
0x01 关于 ascii 编码
因为计算机只能处理数字, 如果要处理文本, 就必须先把文本转换为数字才能处理. 最早的计算机在设计时采用 8 个比特 (bit) 作为一个字节(byte), 所以, 一个字节能表示的最大的整数就是 255(二进制 11111111 = 十进制 255), 如果要表示更大的整数, 就必须用更多的字节. 比如两个字节可以表示的最大整数是 65535,4 个字节可以表示的最大整数是 4294967295.
由于计算机是美国人发明的, 因此, 最早只有 127 个字符被编码到计算机里, 也就是大小写英文字母, 数字和一些符号, 这个编码表被称为 ASCII 编码, 比如大写字母 A 的编码是 65, 小写字母 z 的编码是 122.
但是要处理中文显然一个字节是不够的, 至少需要两个字节, 而且还不能和 ASCII 编码冲突, 所以, 中国制定了 GB2312 编码, 用来把中文编进去.
因此, Unicode 应运而生. Unicode 把所有语言都统一到一套编码里, 这样就不会再有乱码问题了.
0x02 关于 Unicode 编码
Unicode 把所有语言都统一到一套编码里, 这样就不会再有乱码问题了.
ASCII 编码是 1 个字节, 而 Unicode 编码通常是 2 个字节.
字母 A 用 ASCII 编码是十进制的 65, 二进制的 01000001;
字符 0 用 ASCII 编码是十进制的 48, 二进制的 00110000, 注意字符'0'和整数 0 是不同的;
汉字中已经超出了 ASCII 编码的范围, 用 Unicode 编码是十进制的 20013, 二进制的 01001110 00101101.
你可以猜测, 如果把 ASCII 编码的 A 用 Unicode 编码, 只需要在前面补 0 就可以, 因此, A 的 Unicode 编码是 00000000 01000001.
如果统一成 Unicode 编码, 乱码问题从此消失了. 但是, 如果你写的文本基本上全部是英文的话, 用 Unicode 编码比 ASCII 编码需要多一倍的存储空间, 在存储和传输上就十分不划算.
所以, 本着节约的精神, 又出现了把 Unicode 编码转化为 "可变长编码" 的 UTF-8 编码. UTF-8 编码把一个 Unicode 字符根据不同的数字大小编码成 1-6 个字节, 常用的英文字母被编码成 1 个字节, 汉字通常是 3 个字节, 只有很生僻的字符才会被编码成 4-6 个字节. 如果你要传输的文本包含大量英文字符, 用 UTF-8 编码就能节省空间:
在计算机内存中, 统一使用 Unicode 编码, 当需要保存到硬盘或者需要传输的时候, 就转换为 UTF-8 编码.
用记事本编辑的时候, 从文件读取的 UTF-8 字符被转换为 Unicode 字符到内存里, 编辑完成后, 保存的时候再把 Unicode 转换为 UTF-8 保存到文件:
浏览网页的时候, 服务器会把动态生成的 Unicode 内容转换为 UTF-8 再传输到浏览器: 浏览网页的时候, 服务器会把动态生成的 Unicode 内容转换为 UTF-8 再传输到浏览器:
0x03 python3 的编码细节
python3 默认的编码为 unicode,utf-8 可以看做是 unicode 的一个扩展集
encode: 指明要使用的编码, decode: 指明当前编码的编码格式
0x04 python2 和 python3 的一些不同
1) python2 中默认使用 ascii,python3 中默认使用 utf-8
2) Python2 中, str 就是编码后的结果 bytes,str=bytes, 所以 s 只能 decode.
3) python3 中的字符串与 python2 中的 u'字符串', 都是 unicode, 只能 encode, 所以无论如何打印都不会乱码, 因为可以理解为从内存打印到内存, 即内存 ->内存, unicode->unicode
4) python3 中, str 是 unicode, 当程序执行时, 无需加 u,str 也会被以 unicode 形式保存新的内存空间中, str 可以直接 encode 成任意编码格式, s.encode('utf-8'),s.encode('gbk')
- #unicode(str)-----encode---->utf-8(bytes)
- #utf-8(bytes)-----decode---->unicode
5)在 Windows 终端编码为 gbk,Linux 是 UTF-8.
来源: http://www.bubuko.com/infodetail-3074141.html