一个经常听见的问题,那便是:Python 是解释型的语言吗?它会被编译吗?这个问题无想象中那样好回答。和非常多人认识世界同样,习惯以一个简单的模型去评判有些事物。而事实上,里面包括了非常多非常多的细节。
一般的说法,编译表率着将一个高级语言转化为 CPU 能执行的设备码。当你编译 C 的时候,的确是做的这样的操作。编译的结果是一个二进制可执行文件,此时你的系统可直接运行这个程序。
与此相对的,解释的意思是这般的:程序运行时每次读源文件中的一行代码,并执行相应的操作,就这般一行一行的重复下去。当然,所说的脚本语言便是这么运行的。
但事实上,上面的定义有太多的局限。一门真正的语言,为了持有更加多有用和强大的特性,一般采用了各样各样的实现方式。咱们能够将编译理解为更通用有些:将一种语言转化为另一种语言形式。一般来讲,源语言比目的语言要更高级有些,例如将 C 转化为设备码。当然,JavaScript 8 到 JavaScript 5 的转化亦算是一种编译。
在 Python 中,源代码会被编译为更低级的一种形式,咱们叫作之为字节码。字节码是一串指令,和 CPU 的指令集类似。然则字节码并不直接被 CPU 执行,而是在虚拟机中执行的。当然,这儿的虚拟机并不模仿全部操作系统的环境,只是供给了字节码执行的一个环境。
下面咱们看 Python 的一小段代码以及它对应的字节码
看了字节码的内容后,咱们就晓得 f... 这种格式化字符串的形式的运行原理,便是将里面的字符串转化为一系列的字面字符串与变量,而后运用 + 号连接起来。
dis 是 Python 标准库中反汇编模块,它能够展示 Python 代码的字节码信息。上面说到的执行字节码的虚拟机,能够用任意的语言实现,包含 Python 自己。有兴趣的能够去 GitHub 上看下这个项目 nedbat/byterun 。这个项目能够用来学习,但不适用于生产环境。
不外,咱们运行 Python 时完全感受不到它的编译过程,无表示的调用什么编译程序,仅仅是简单的执行 .py 文件,编译都是必须时自动编译的。这和 JAVA 区别,当你每次写完 JAVA 代码要执行时,都要手动将其编译为 .class 文件,而后执行。亦正是这个原由,JAVA 被叫作为编译型语言,而 Python 被叫做解释型语言。但事实上,两种语言执行时都会先编译成字节码,而后交给虚拟机执行。
Python 还有一个重要的特性,便是交互式命令行。你能够敲入一行 Python 语句,而后立刻回车执行。实质上,即使是这个过程,Python 一样是先转为字节码,而后执行。而这个交互式命令行这个特性,在非常多编译型语言里是无的。一样由于无表示的调用编译程序,非常多人将执行 Python 源文件的程序叫做 Python 解释器。
即使比较简略,但还是弥补下。部分编译型语言例如 C 或 JAVA 亦有交互式命令行,但这些并不是这些语言的重心。JAVA 刚起始是编译成字节码而后执行,后面有了即时编译技术( JIT )能够直接编译成设备码,与 C 类似。
从上面的描述能够看出,不管是解释还是编译,并没法完全分离开来。非常多时候,咱们想用有些词将现有的编程语言分个类,但事实上要办到这一点太难了。
最后要说明的是,你的代码是怎么执行的只是语言的实现问题,并非语言的特征。上文中,咱们讨论的是 Python ,但实质上是 CPython 的描述。CPython 是一个解释器,之因此这么叫,是由于这个解释器是用 C 编写的,这亦是 Python 默认的解释器。当然还有其它非常多解释器,例如,PyPy 便是另一种解释器,运用了 JIT 技术,运行速度相比 CPython 有很强提高。
回到标题中的问题,Python 之因此叫作为解释型语言,是由于它无表示的调用编译操作,表现出解释型的特性比较多罢了。但事实上,编译是存在的,详细怎么编译就看语言的实现了,亦便是解释器的设计。
|