Python是解释型、编译型还是两者兼有?

299 投票
16 回答
289162 浏览
提问于 2025-04-16 22:36

根据我的理解:

解释型语言是一种高级语言,它通过一个叫做解释器的程序来运行和执行。这个解释器会把高级语言转换成机器代码,然后逐步执行程序,也就是说,它是边处理边运行的。

编译型语言则是另一种高级语言,它的代码首先会被一个叫做编译器的程序转换成机器代码,然后再由另一个程序来执行这些代码。

如果我的定义有错,请纠正我。

现在回到Python,我对此有点困惑。到处都说Python是一种解释型语言,但它其实是先被转换成某种中间代码(比如字节码或IL),而不是直接转换成机器代码。那么,哪个程序来执行这些中间代码呢?请帮我理解一下Python脚本是如何处理和运行的。

16 个回答

50

这个问题的答案其实要看你用的是什么版本的Python。如果你用的是CPython(Python的标准版本)或者Jython(专门为Java编程语言设计的版本),那么代码首先会被转换成字节码。然后,根据你使用的Python版本,这个字节码会被送到相应的虚拟机进行解释。比如,CPython会用PVM(Python虚拟机),而Jython则会用JVM(Java虚拟机)。

不过,如果你用的是PyPy,这也是一种标准的CPython实现,它会使用一种叫即时编译器的东西。

66

CPU其实只能理解机器代码。对于解释型程序来说,解释器的最终目标就是把程序代码“翻译”成机器代码。不过,现代的解释型语言通常不会直接把人写的代码翻译成机器代码,因为那样效率太低了。

以Python为例,Python解释器首先会读取人写的代码,然后把它优化成一种中间代码,再进一步翻译成机器代码。这就是为什么你每次运行Python脚本时都需要另一个程序来帮忙,而不像C++那样可以直接运行编译好的可执行文件。比如,你可能会用到 c:\Python27\python.exe/usr/bin/python 这样的命令。

365

首先,解释型和编译型并不是语言本身的特性,而是实现方式的特性。对于大多数编程语言来说,大部分实现都属于某一类,所以有时候我们可以简单地说这门语言是解释型或编译型,但这其实是个重要的区别,因为它有助于理解。而且,有不少语言同时有这两种可用的实现(主要是在函数式编程语言中,比如Haskell和ML)。此外,还有一些C语言的解释器和项目,试图将Python的某些部分编译成C或C++代码(然后再转成机器码)。

其次,编译并不仅仅是指提前将代码编译成本地机器码。更广泛地说,编译器是一个将一种编程语言的程序转换成另一种编程语言的程序(可以说,即使输入和输出语言相同,只要进行了重要的转换,也可以算作编译)。而JIT编译器是在程序运行时将代码编译成本地机器码,这样的速度可以接近甚至超过提前编译的速度(这取决于基准测试和不同实现的质量)。

不过,为了不再纠结细节,来回答你想问的问题:实际上(也就是说,使用一些比较流行和成熟的实现),Python是编译过的。不是提前编译成机器码(也就是常见但不太准确的定义),而是“仅仅”编译成字节码,但这仍然算是编译,至少有一些好处。例如,语句a = b.c()会被编译成一个字节流,当“反汇编”后,看起来像load 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a)。这只是个简化,实际上可读性更差,层次更低——你可以试试标准库中的dis模块,看看真实的样子。解释这个字节码的速度比直接从更高层次的表示中解释要快。

这个字节码要么被解释(注意,直接解释和先编译成某种中间表示再解释之间在理论和实际性能上是有区别的),就像参考实现(CPython)那样,要么在运行时被解释和编译成优化过的机器码,就像PyPy那样。

撰写回答