编码

为什么会有编码,以及编码的发展历程?

  很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物。他们看到8个开关状态是好的,于是他们把这称为”字节“。再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出很多状态,状态开始变来变去。他们看到这样是好的,于是它们就这机器称为”计算机“。

  这八个开合的晶体管的随机组合得到了256种不同的状态,所以得到了不通的字节

  一个或多个字节的组合,我们称为字符

  

  根据组成字符字节数据的不同,有不同的编码方式:ASCII Unicode UTF-8 GBK GBK-2312等

使用字符编码如何操作计算机?

 人们把其中的编号从0开始的32种状态分别规定了特殊的用途,一但终端、打印机遇上约定好的这些字节被传过来时,就要做一些约定的动作:  

  遇上0×10, 终端就换行;

  遇上0×07, 终端就向人们嘟嘟叫;

  遇上0x1b, 打印机就打印反白的字,或者终端就用彩色显示字母。

人们看到这样很好,于是就把这些0×20以下的字节状态称为”控制码”。

 ASCII的出现

人们把所有的空格、标点符号、数字、大小写字母分别用连续的字节状态表示,一直编到了第127号,这样计算机就可以用不同字节来存储英语的文字了。大家看到这样,都感觉
很好,于是大家都把这个方案叫做 ANSI 的”Ascii”编码(American Standard Code for Information Interchange,美国信息互换标准代码)
所占字节数:1个字节

GBK的出现

背景:
  世界各地都开始使用计算机,但是很多国家用的不是英文,他们的字母里有许多是ASCII里没有的,为了可以在计算机保存他们的文字,他们决定采用127号之后的空位来表示这些新的字母、符号,还加入了很多画表格时需要用下到的横线、竖线、交叉等形状,一直把序号编到了最后一个状态255。从128 到255这一页的字符集被称”扩展字符集“。从此之后,贪婪的人类再没有新的状态可以用了!中国人们得到计算机时,已经没有可以利用的字节状态来表示汉字,况且有6000多个常用汉字需要保存呢
出现:
  把那些127号之后的奇异符号们直接取消掉, 规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字
所占字节数:ascii表中,占一个字节  中文占两个字节

Unicode的出现

背景:
  由于各个国家都搞出了自己的编码流程,结果互相之间谁也不懂谁的编码,谁也不支持别人的编码。
出现:
  ISO(国际标谁化组织)的国际组织决定着手解决这个问题。他们采用的方法很简单:废了所有的地区性编码方案,重新搞一个包括了地球上所有文化、所有字母和符号 的编码!他们打算叫它”Universal Multiple-Octet Coded Character Set”,简称 UCS, 俗称 “unicode
所占字节数 : 同一占两个字节

UTF-8的出现

背景:
  unicode同样也不完美,英文字母只用一个字节表示就够了,如果unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储空间来说是极大的浪费,文本文件的大小会因此大出二三倍,这是难以接受的。
出现:
  为解决unicode如何在网络上传输的问题,于是面向传输的众多 UTF(UCS Transfer Format)标准出现了,顾名思义,UTF-8就是每次8个位传输数据,而UTF-16就是每次16个位。UTF-8就是在互联网上使用最广的一种unicode的实现方式,这是为传输而设计的编码,并使编码无国界,这样就可以显示全世界上所有文化的字符了。UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度,当字符在ASCII码的范围时,就用一个字节表示,保留了ASCII字符一个字节的编码做为它的一部分,注意的是unicode一个中文字符占2个字节,而UTF-8一个中文字符占3个字节)。从unicode到utf-8并不是直接的对应,而是要过一些算法和规则来转换。
所占字节数:ascii表中的元素占一个字节  欧洲文字占两个字节  中文占3个字节
 

文件从磁盘到内存的编码(******)

 当我们在文本编辑器(word等)上编辑文字的时候,不管是中文还是英文,计算机都是不认识的,那么在保存之前数据是通过什么形式存在内存的呢?
   Unicode数据
使用原因:无论英文,中文,日文,拉丁文,世界上的任何字符它都有唯一编码对应,所以兼容性是最好的
那当我们保存了存到磁盘上的数据又是什么呢?  
  是通过某种编码方式编码的bytes字节串。比如utf8 
使用原因:节省了空间 
文本编辑器的编码与解码过程:
  保存文件:文本编辑器软件都有默认的保存文件的编码方式,比如utf8,比如gbk。当我们点击保存的时候,这些编辑软件已经"默默地"帮我们做了编码工作。
  打开文件:当我们再打开这个文件时,软件又默默地给我们做了解码的工作,将数据再解码成unicode,然后就可以呈现明文给用户了!
总结:unicode是离用户更近的数据,bytes是离计算机更近的数据。

 python2与python3的编码方式

python2默认编码方式:ASCII

python3默认编码方式:UTF-8

python2与python3的字符串类型

python2 str == python3 bytes

python2 unicode == python3 str

常见的编码问题

1 cmd下的乱码问题

原因:

  我们在win下的终端即cmd.exe去执行,大家注意,cmd.exe本身也一个软件;当我们python2 hello.py时,python2解释器(默认ASCII编码)去按声明的utf8编码文件,而文件又是utf8保存的,所以没问题;问题出在当我们print'苑昊'时,解释器这边正常执行,也不会报错,只是print的内容会传递给cmd.exe用来显示,而在py2里这个内容就是utf8编码的字节数据,可这个软件默认的编码解码方式是GBK,所以cmd.exe用GBK的解码方式去解码utf8自然会乱码。

py3正确的原因是传递给cmd的是unicode数据,cmd.exe可以识别内容,所以显示没问题。

解决方法:print (u'苑昊')

2 open()中的编码问题

原因:

  因为你的win的操作系统安装时是默认的gbk编码,而linux操作系统默认的是utf8编码;

当执行open函数时,调用的是操作系统打开文件,操作系统用默认的gbk编码去解码utf8的文件,自然乱码。

解决方法:指定utf-8解码方式

字节码和机械码

机械码:由0,1组成的二进制代码,这种类型的代码即称为机器码,机器码是计算机可以直接执行的、速度最快的代码

python的字节码:

  当我们运行python文件程序的时候,Python解释器将源码转换为字节码,然后再由解释器来执行这些字节码。

执行流程: 

  1. 完成模块的加载和链接;
  2. 将源代码翻译为PyCodeObject对象(这货就是字节码),并将其写入内存当中(方便CPU读取,起到加速程序运行的作用);
  3. 从上述内存空间中读取指令并执行;
  4. 程序结束后,根据命令行调用情况(即运行程序的方式)决定是否将PyCodeObject写回硬盘当中(也就是直接复制到.pyc或.pyo文件中);
  5. 之后若再次执行该脚本,则先检查本地是否有上述字节码文件。有则执行,否则重复上述步骤。

字节码文件:文件名以.pyc结尾,或许你已经听说过它们就是Python的“字节码”文件。(但在Python 3上却难觅其踪 -- 原因是它们不再与.py文件出现在同一个目录中,而是放在一个名为__pycache__的子目录中了)。或许你也已听说过这是一种程序加速机制。通过防止Python每次运行时都重新解析源代码从而加快程序运行。一般py文件改变后,都会重新生成pyc文件。

主动生成pyc文件:

  为什么?主要是不想把源代码暴露出来。

  生成单个

  1 python -m foo.py

  2 import py_compile

     py_compile.compile('/path/to/foo.py')

  批量生成pyc文件

  import compileall

  compileall.compile_dir(r'/path')

参考:https://www.cnblogs.com/575dsj/p/7112767.html

     https://www.zhihu.com/question/23374078/answer/69732605

     https://blog.csdn.net/m0_37550221/article/details/78907972

原文地址:https://www.cnblogs.com/benson321/p/10053087.html