字符编码
首先了解一下字符编码表:
字符表码表就是人类规定的字符与计算机语言的对应关系的对照表
ascii码
最初的字符编码表为ASCII码:
其中只包含了英文字母以及一些符号,数字,由8位二进制为单位,即一个字节
GBK
后来随着时代的变化,其他国家的人也需要将自己的语言加入其中,而ASCII码无法满足这个需求,便形成了各种不同的字符编码表,中国有GBK,日本有Shift_JIS...等等
以中国制定的GBK为例: GBK用一个字节表示英文的一个字母,用两个字节表示中文的一个字。
小tip:
GBK中如何识别“w上u”呢,是每次取一个字节还是每次取两个字节呢?
答案是都不对,GBK中每个字节的第一位是用来表示它是英文还是中文的,如果是英文,第一位就是0,就会取一个字节,如果是中文,第一位就是1,就会取两个字节,而这会导致有时python中字符串编码成GBK显示的数值和GBK与unicode对照表中的数值不同,如res = "上".encode("GBK")里res的结果是b'xc9xcf',而对照表中显示“上”的编码应该为494f,这里面的原因就是字节的第一位用来表示中英文了,python中将第一位的数字也算在其中,即0b1100 == 12 == 0xc,而0b100 == 4
unicode
后来各国又发现各种字符编码表不能互通,一旦跨国,字符便成了乱码,又诞生了包含万国语言的万国码unicode。unicode常用2个字节(16位二进制)代表一个字符,生僻字需要用4或8个字节。
unicode表:
内存
人类的字符---------unicode格式的数字----------
| |
| |
|
硬盘 |
|
| |
| |
GBK格式的二进制 Shift-JIS格式的二进制
老的字符编码都可以转换成unicode,但是不能通过unicode互转
utf-8
这时候乱码问题消失了,所有的文档我们都能使用,但是新问题出现了,如果我们的文档通篇都是英文,你用unicode会比ascii耗费多一倍的空间,在存储和传输上十分的低效
本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8
编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,
用UTF-8(全称Unicode Transformation Format)编码就能节省空间。
python解释器执行.py文件的原理
例如python test.py
#第一阶段:python解释器启动,此时就相当于启动了一个文本编辑器
#第二阶段:python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中(pyhon的解释性,决定了解释器只关心文件内容,不关心文件后缀名)
#第三阶段:python解释器解释执行刚刚加载到内存中test.py的代码( ps:在该阶段,即真正执行代码时,才会识别python的语法,执行文件内代码,当执行到name="egon"时,会开辟内存空间存放字符串"egon")
总结:
1.编码
内存中统一采用unicode,浪费空间来换取可以转换成任意编码(不乱码),硬盘可以采用各种编码,如utf-8,保证存放于硬盘或者基于网络传输的数据量很小,提高传输效率与稳定性。
基于目前的现状,内存中的编码固定就是unicode,我们唯一可变的就是硬盘的上对应的字符编码。
字符--------->内存-------->硬盘
英文+汉字---->unicode----->gbk
英文+日文---->unicode----->shift-jis
万国字符----->unicode----->utf-8
小tip
关于为什么现在内存中还使用unicode,而不直接换成utf-8呢?
因为现在还存在各种不同的编码表,需要用unicode来转化成可识别的字符,
而什么时候GBK等各国编码表不再使用,我们就可能直接将硬盘-----内存的数据全部使用utf-8
2、文本文件存取乱码问题
存乱了:解决方法是,编码格式应该设置成支持文件内字符串的格式
取乱了:解决方法是,文件是以什么编码格式存如硬盘的,就应该以什么编码格式读入内存
3、python解释器默认读文件的编码
python3中默认读:utf-8
python2中默认读:ASCII
指定文件头修改默认的编码:
在.py文件的首行写:# coding:gbk
4、保证运行python程序前两个阶段不乱码的核心法则:
4.1 指定文件头
4.2 coding:文件当初存入硬盘时所采用的编码格式
5、保证运行python程序第三个阶段不乱码的核心法则:
python3的str类型默认直接存成unicode格式,无论如何都不会乱码
保证python2的str类型不乱码: 在字符串前加上u
x=u'str'
6、了解
python2解释器有两种字符串类型:str、unicode
str类型
x='上' # 字符串值会按照文件头指定的编码格式存入变量值的内存空间
unicode类型
x=u'上' # 强制存成unicode
7、bytes转为字符
bytes.decode(data)