Python进阶I,Python的编译
Python在执行阶段,作为程序的主模块首先需要编译,然后进行解释,将二进制代码解释成CPU中的指令。
编译的过程是什么样的呢?
Python编译器首先将code编译成多个代码行,这个行是逻辑行
逻辑行是由一个物理行,或多个通过显示或隐式行连接规则连接在一起的物理行组成的。
物理行就是各个平台下的换行+回车的二进制代码的表示,其中windows是\r\n,linux是\n。将换行+回车以NEWLINE标记替换。
显示行连接规则是通过在多个物理行中使用 “\” 合并,这个合并的检测是在检测\n如果出现\n则说明下一行也是逻辑行。其中将\n以NEWLINE标记替换。
隐式行连接规则则是检测如果在开头有(,[,{这三种,则后面无论跨越多少行,只要没有出现),],}都视为一个逻辑行。其中在),],}后加入NEWLINE标记。
关于注释,注释是通过检测是否存在#字符,正常情况下如果在一行中出现了#字符,则#字符后面不计入逻辑行,直接在#字符前加入NEWLINE标记。
关于NEWLINE标记的设想,众所周知,我们最开始写的code就是一群二进制代码,其中包含了换行符号,空格符号,tab符号,换页符号以及代码,注释等等,编译首先需要做的是什么?
就是将其二进制代码进行处理,将其中的代码指令按序提取出来,模拟一下编译的执行过程,首先编译程序在CPU中运行,第一步将code从硬盘中读到内存中,然后将code再从内存中读入CPU的寄存器中,然后根据编译程序的指令+code作为数据,进行分析处理,这个时候要划分出逻辑行,作为代码执行的一个小的代码块,而这个逻辑行的区分是通过什么来划分的呢?
这就是通过添加NEWLINE标记来进行区分的
代码块划分完成了,那么接下来应该怎么做呢?
接下来就是对于缩进的处理了,来进行分层次。
缩进是通过空格符号来代表的,其中tab键被认为是多个空格符号,具体几个可以设定。
第一个非空字符前的空格数决定了行的缩进格式,例如在第一个字符前有两个空格,那么他的下一层应该是4个空格。
在缩进的过程中使用了栈的数据结构,文件的第一行未被读取前,一个0被压入栈中,以后再也不会被弹出,栈的特性是先进后出,栈顶永远是最后进的数字。在每个逻辑行的开头处,先获得空格符号的个数,然后和栈顶比较:
如果相等则说明处于同一个层次,则什么都不做
如果大于则说明处于栈顶的下一层次,这个时候就会在该代码块中加入INDENT符号(猜测是在该代码块的头部)
如果小于栈顶元素,说明上一层次已经结束了,这个时候,栈会弹出所有大于该空格数的数字,然后在这一代码块(头部)加入DEDENT语言符号
文件的结尾处如果栈中的元素仍然大于1,则说明层次已经结束,例如:
if a>1:
if b>2:
c=3
这个时候就在c=3这个代码块中,也就是逻辑行的尾部加入一个DEDENT语言符号,示意已经结束。
tap:在编译的过程中,缩进分层和分割逻辑行应该同时进行的,没有先后顺序之分,只不过为了说明,我主观的将其进行了一个先后。
在缩进分层和分割逻辑行的同时,对于code文件中的代码也进行了编译,这个编译是对于代码进行处理。
ps:关于主程序编译后不保存,然后对于导入新的模块时,进行编译保存这些将会在import时说明。