2020年5月3日 / 888次阅读 / Last Modified 2020年5月3日
关于这个问题,谈谈我的个人看法。python是解释型语言,python官方tutor里面的介绍,说的也是 its interpreted nature, and python interpreter,翻译过来是python解释执行的本质和python解释器。这里面都没有提到编译。
但是,python有编译,它有py_compile和compileall标准模块,还有builtin的compile函数。为什么一个解释型的编程语言,还有编译呢?(编译python文件)
问题回到了我们应该如何去理解解释型的语言?
应该这样说,一个编程语言是不是解释型的,跟是否要编译没有关系。而且,编译这个概念也要扩展一下,C语言的编译,其实是编译链接,最后得到的是一个只有机器码的文件;而python的编译,就是编译为python byte code,与任何CPU无关,只有python解释器能看懂的字节码。
所谓解释型语言的判定,应该是其是否可以一行一行地一遍翻译(或编译)一遍执行!python解释器本质上就是一行行执行代码,比如你在使用交互式的python解释器的时候。而C语言,显然不能一行一行地执行,因此它是编译型的编程语言。
有python经验的同学,可能都遇到过这样的情况。有一些python代码中的bug,一定要运行到那段代码的时候,才能被解释器抛出来。典型的异常就是NameError,一个函数中使用了一个变量,但是此变量不存在。python的编译过程是不能发现这类bug的,只有函数在被调用执行的时候,直到执行到那一行包含不存在变量的代码时,NameError才会被抛出来。而C就不一样,所有的变量都要事先申明,编译过程会发现所有未申明的变量。
python代码会被编异常byte code,然后在解释中一行行地执行byte code。byte code至于python解释器有关,python解释器相当于一台虚拟机,有自己的“机器码”!C语言编译之后,可直接在CPU上运行(当然需要OS的调度),而CPU本质上也是一行行地执行它的机器码,CPU就是一个机器码解释器。但python的byte code不会被编译成本地CPU的机器码(至少python解释器自己不会干,有第三方库可以干这个事情)。所以,是否会被编译成本地CPU的机器码,可能也是一个解释型语言和编译型语言的区别角度。
还有python的动态类型,和一切皆为对象。这些特性我认为都与其本质上是解释型的语言有关系。解释,一行行地将高级逻辑表达翻译成可以被执行的代码!编译,将代码翻译成CPU机器码!Shell脚本就是在做解释执行,其执行就是在解释后调用不同的程序来完成对应的动作,这个过程没有编译成CPU机器码的部分,其调用的子程序,都是已经编译好了的。
-- EOF --
本文链接:https://www.pynote.net/archives/1864
《python是解释型语言,为啥还要编译?》有3条留言
©Copyright 麦新杰 Since 2019 Python笔记
Python checks the modification date of the source against the compiled version to see if it’s out of date and needs to be recompiled. This is a completely automatic process. Also, the compiled modules are platform-independent, so the same library can be shared among systems with different architectures. [ ]
编译,其实也是翻译,把一种表达方式编程另一种表达方式。 [ ]
C#语言是编译型语言,但其“编译”过程比较特殊,具体说明如下: C#程序在第一次运行的时候,会依赖其.NET Frameworker平台,编译成IL中间码),然后由JIT compiler翻译成本地的机器码执行。从第二次在运行相同的程序,则不需要再执行以上编译和翻译过程,而是直接运行第一次翻译成的机器码。所以对于C#来说,通常第一次运行时间会很长,但从第二次开始,程序的执行时间会快很多。 那么,C#为什么要进行两次“编译”呢?其实,微软想通过动态编译(由JIT compiler工具实现)来实现其程序运行的最优化。如果代码在运行前进行动态编译运行,那么JIT compiler可以很智能的根据你本地机器的硬件条件来进行优化,比如使用更好的register,机器指令等等,而不是像原来那样,build一份程序针对所有硬件的机器跑,没有充分利用各个机器的条件。 [ ]