# python3中string.encode()之后
# 引言
在学习python的时候,就耳闻python2中的string会时不时出现很奇怪的unicode error。没办法,自认为是个傻瓜,又想偷懒,所以就直接学习python3了,但是无论如何选择,字符串是一个编程语言必须面对的情景,也必须提供对字符串的支持。虽说在python3中,python改善了2中ascii和unicode隐式转换的坑,但是如果不了解背后的知识,还是比较容易遇到编码的错误。那么就来学一学,记一记。
# 问题
在python3处理字符串的时候,会频繁的遇到编码解码的情况,即encode()、decode()。
如上例,字符串一被编码之后出现了一串字母数字的组合,那么这个东西要怎么解释呢?
# 求知之路
# 1. 疯狂的search
首先在遇到问题,一头雾水的时候,这正是由于自己掌握的情报比较少,无从下手,这时就需要借助整个人类的力量,在搜索引擎中的海量资源中寻找有用的知识,下面是我找到的一篇文章,给我搜寻答案下的方向。
这篇文章总结了5个事实,那把这5个事实当做结论拿出来。 进程的输入输出的都是bytes。
编程中文本不止256个符号。
进程必须处理byte和unicode。
byte流中不会包含编码信息。
指明的编码可能是错误的。
# 2. 理解byte
可以知道的是bit是0或者1,占一位,而byte是8个bit的组合,叫做字节。从上面的搜索来看,在进程中输入输出都是按照bytes来的,也就是进程,或者说计算机接收或者处理的最小单位是byte。哎?不是还有bit吗?确实计算机中信息的最小单位是bit,但是bit表示电平的开闭,由于一个bit并不能表示计算机经常处理的信息,所以在计算机中都是将8个bit组合在一起成byte来表示信息。这样进程输入输出(I/O),计算机存储,与网络传输的最小单位就是byte,毕竟如果用bit传输,根本无法判断传输的边界。
# 3. unicode
在计算机,网络从USA扩展到非英语世界后,传统的使用一个byte来表示英语世界中的,数字,字母,及一些常用的符号的机制就失效了,由于一个byte只有8bit,即只能存储256种信息,而世界上的中文字符,日文字符,阿拉伯字符可不只256种,所以在经过研究,各国都拿出来自己的标准,又不相通,导致一段时间的混乱,最后拿出了unicode方案,unicode规范中,unicode4.0采用了4byte来表示字符,这样就可以表示一百多万个字符,目前只把unicode码中的几十万个码映射到具体的字符上了。就是说unicode规定了一个字符对应的整数值,比如一对应的值就是19968,这个值叫做code point。
# 4. unicode和utf-8
unicode和utf-8,有了unicode就可以表示世界上所有的字符了,那么为什么还有utf-8等呢?
那是因为unicode4.0使用4个byte来表示字符,那么如果我要表示a这个字符呢?它的code point值为97,要是原原本本的使用unicode来表示那么就成了00000000 00000000 00000000 01100001,这样一看就知道前面的3byte是不要的,所以还需要一种规则来翻译unicode。utf-8出世!utf-8编码规则是一种变长的编码规则,通过上面的例子可以看出,在表示英文字符是实际上并不需要4个byte,只要一个byte就可以了。而对于中文,则需要2-4个byte。
UTF-8编码规则: 对于对于单字节字符,这个字节的第1位为0,后7位为unicode码,所以对于英文来讲utf-8编码和ASCII编码时一样的。
对于n字节字符,第一个字节的前n位为1,n+1位为0,后面n-1个字节的前两位都为10,其他位放置unicode码。 Unicode符号范围(十六进制) UTF-8编码方式(二进制) 0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
最后提一个知乎上很好的总结:unicode是字符集,uft-8是编码规则
# 5. 最终解释
对于一,可以通过python的ord函数来查看这个字符的unicode code point。
那么python中encode之后的一串符号表示的是什么呢?
实际上,python3中encode()之后会得到一个byte串,这个byte串中存放着编码值,比如上例中使用encode(),没有传入参数,则默认的是utf-8编码。那么得到的byte串也就存放着utf-8从unicode通过一些规则得到的码值了,我们将它们转换会去看看。