原文出处:https://www.cnblogs.com/alex3714/articles/7550940.html
编码种类
- ASCII占1个字节,只支持英文
- GB2312占2个字节,支持6700+汉字
- GBK GB2312的升级版,支持21000+汉字
- Shift-JIS日本字符
- TIS-620 泰国编码
由于每个国家都有自己的字符,所以其对应关系也涵盖了自己国家的字符,但是以上编码都存在局限性,即:仅涵盖本国字符,无其他国家字符的对应关系。应运而生出现了万国码,他涵盖了全球所有的文字和二进制的对应关系
- unicode 2-4字节,已经收录了136690个字符,一直在不断增长..
Unicode起到了两个作用:
- 直接支持全球所有语言,每个国家都可以不再使用自己之前的旧编码了,用unicode就可以了。(就跟英语是全球统一语言一样)
- unicode包含了跟全球所有国家编码的映射关系。
Unicode解决了字符和二进制的对应关系,但是使用unicode表示一个字符,太浪费空间。例如:利用unicode表示“Python”需要12个字节才能表示,比原来ASCII表示增加了1倍。
由于计算机的内存比较大,并且字符串在内容中表示时也不会特别大,所以内容可以使用unicode来处理,但是存储和网络传输时一般数据都会非常多,那么增加1倍将是无法容忍的!!!
为了解决存储和网络传输的问题,出现了Unicode Transformation Format,学术名UTF,即:对unicode中的进行转换,以便于在存储和网络传输时可以节省空间!
- UTF-8: 使用1、2、3、4个字节表示所有字符;优先使用1个字符、无法满足则使增加一个字节,最多4个字节。英文占1个字节、欧洲语系占2个、东亚占3个,其它及特殊字符占4个
- UTF-16: 使用2、4个字节表示所有字符;优先使用2个字节,否则使用4个字节表示。
- UTF-32: 使用4个字节表示所有字符;
总结:UTF是unicode编码 设计的一种 在存储和传输时节省空间的编码方案。
字符在硬盘上的存储
无论以什么编码在内存里显示字符,存到硬盘上都是2进制。
需要注意的是,以某种编码存到硬盘,从硬盘读出来的时候就必须用那种编码读,要不然就乱了。
python3的执行过程
- 解释器找到代码文件,把代码字符串按文件头定义的编码加载到内存,转成unicode
- 把代码字符串按照语法规则进行解释
- 所有的变量字符都会以unicode编码声明
如果使用python3的话,我们用utf8编码的文件可以在windows下的终端(gbk)正常显示,是因为到了内存里python解释器会把utf8转成unicode,在输出的时候,如果你的终端是gbk编码的或者是utf8编码的,python3就会把unicode转成gbk或utf8。(unicode可以和任意编码格式灵活转换)
但仅限于python3,并不是所有的变成语言在内存里默认编码都是unicode的,比如 python2就不是,它的默认编码是ASCII,想写中文,就必须声明文件头的coding为gbk or utf8,声明之后,python2的解释器仅以文件头声明的编码去解释你的代码,加载到内存后,并不会主动帮你转成unicode,也就是说,你的文件编码是utf-8,加载到内存里,你的变量字符串就也是utf8,意味着,你以utf8编码的文件,在windows是乱码..
既然Python2并不会自动的把文件编码转为unicode存在内存里, 那就只能使出最后一招了,你自己人肉转。Py3 自动把文件编码转为unicode必定是调用了什么方法,这个方法就是,decode(解码) 和encode(编码)
UTF-8 --> decode 解码 --> Unicode Unicode --> encode 编码 --> GBK / UTF-8 ..
python bytes类型
在python2中,byte==str, unicode是一个单独类型
由于Python创始人在开发初期认知的局限性,其并未预料到python能发展成一个全球流行的语言,导致其开发初期并没有把支持全球各国语言当做重要的事情来做,所以就轻佻的把ASCII当做了默认编码。 当后来大家对支持汉字、日文、法语等语言的呼声越来越高时,Python于是准备引入unicode,但若直接把默认编码改成unicode的话是不现实的, 因为很多软件就是基于之前的默认编码ASCII开发的,编码一换,那些软件的编码就都乱了。所以Python 2 就直接 搞了一个新的字符类型,就叫unicode类型,比如你想让你的中文在全球所有电脑上正常显示,在内存里就得把字符串存成unicode类型
python3 unicode==str, byte是一个单独的类型
为什么在py3里,把unicode编码后,字符串就变成了bytes格式? 你直接给我直接打印成gbk的字符展示不好么?我想其实py3的设计真是煞费苦心,就是想通过这样的方式明确的告诉你,想在py3里看字符,必须得是unicode编码,其它编码一律按bytes格式展示。
最后再提示一下,Python只要出现各种编码问题,无非是哪里的编码设置出错了
常见编码错误的原因有:
- python解释器的默认编码
- python源文件文件编码
- Terminal使用的编码
- 操作系统的语言设置