是Python解释还是编译?


76

这只是我在阅读有关解释和编译语言时的一个奇迹。

Ruby无疑是一种解释型语言,因为源代码在执行时由解释器处理。
相反,C是一种编译语言,因为必须先根据机器编译源代码,然后再执行。这样可以更快地执行。

现在开始使用Python

  • 导入时,Python代码(somefile.py)在同一目录中创建文件(somefile.pyc)。让我们说导入是在python shell或django模块中完成的。导入后,我稍稍更改了代码,然后再次执行导入的功能,以发现它仍在运行旧代码。这表明* .pyc文件是类似于编译C文件后创建的可执行文件的已编译python文件,尽管我无法直接执行* .pyc文件。
  • 当直接执行python文件(somefile.py)(./somefile.py或python somefile.py)时,不会创建.pyc文件,并且按指示解释行为的方式执行代码。

这些建议每次在新过程中导入python代码时都会编译python代码,以创建.pyc,而直接执行时会对其进行解释。

那么我应该将其视为哪种类型的语言?解释还是编译?以及它的效率与解释和编译语言相比如何?

根据Wiki的“ 解释语言”页面,它被列为编译为虚拟机代码的语言,这是什么意思?


1
什么时候可以怀疑Ruby是否是一种解释语言?编译时。:) macruby.org
mipadi

8
值得注意的是,没有严格意义上的现代语言被解释。实际上,它们全部都编译为字节码。
Winston Ewert 2010年

@温斯顿·埃韦特:太棒了!Applesoft Basic(在1980年代)是字节代码编译的。在这种情况下,“现代”表示生活记忆中的每种解释语言,唯一可能的例外是一些基本的Dartmouth Basic实现。
S.Lott 2010年

6
>>相反,C是一种编译语言<< root.cern.ch/drupal/content/cint
igouy 2010年

3
@ S.Lott:调用Applesoft和80年代的BASIC解释器执行的令牌化过程是“字节码编译”,这有点不明智。是的,用户输入的程序代码以压缩形式存储在内存中,每个保留字一个字节,但是除非您键入,否则什么都不会做RUN。就像您有一个编译器执行词法分析步骤,然后输出每次运行程序时都必须重新解析的令牌流一样。根本不像说的那样现代的字节码编译javac,它包括词法分析,解析和优化。
dodgethesteamroller

Answers:


80

值得注意的是,语言不会被解释或编译,而是语言实现可以解释或编译代码。您注意到Ruby是一种“解释语言”,但是您可以编译Ruby和MacRuby,因此它并不总是一种解释语言。

几乎每个Python实现都包含一个解释器(而不是编译器)。.pyc您看到的文件是Python虚拟机的字节码(类似于Java的.class文件)。它们与C编译器为本机机器体系结构生成的机器代码不同。但是,某些Python实现确实包含一个即时编译器,该编译器会将Python字节代码编译为本地机器代码。

(我之所以说“几乎每个”,是因为我不知道任何适用于Python的本机编译器,但我不想宣称任何地方都不存在。)


根据您的定义,存在适用于Python的本机编译器。有些只编译python的子集。其他实现所有的蟒蛇,但使用Python API实际执行它不能在C.执行操作
温斯顿·尤尔特

我认为您实际上是在描述Python是我所谓的“半编译”或实际上可以完全编译的。半编译的意思是,由于通常将其编译为Python虚拟机使用的“中间语言” .pyc文件,因此通常以这种“半编译”形式运行,这通常会使代码比解释代码的普通运行时解释。有趣的是,半编译代码有时可能比本地编译的代码快(例如,C#通常比C ++快)。
克里斯·哈克罗

5
Cython将Python代码编译为C,以便可以将其编译为共享对象。
greyfade

以这种方式区分字节码和机器码是相当随意的。编译Java:javac编译器生成包含低级指令的类文件,这些指令可以在虚拟机(例如,热点)中或直接由硬件(例如,在具有Jazelle扩展名的ARM处理器上)执行。据我所知,没有技术上的理由不能将类似的处理器架构设计为直接执行python vm指令。
Jules 2015年

@Jules巧合的是,Jython代码实际上已编译到.class文件中,我相信这些文件将被重用,直到您修改py源。
JimmyJames

35

Python将被解释为字节码。.py首先将源代码编译为字节码.pyc。可以解释该字节码(官方CPython),或编译JIT(PyPy)。Python源代码(.py)可以编译为不同的字节代码,例如IronPython(.Net)或Jython(JVM)。Python语言有多种实现。官方的一种是字节码解释的。也有JIT编译的字节码实现。

对于各种语言实现的速度比较,您可以在这里尝试。


thanx的信息。根据基准测试,python的性能下降了!
crodjer 2010年

1
我给的链​​接非常清楚地指出,这些是语言实现的基准。如果您过于担心执行性能,那么Python不应是您选择的语言。如果仍要比较,请比较相似的语言。字节码解释的官方CPython可以与JIT编译的Ruby相媲美或更快。
2010年

1
@ jase21-“我在2006年的计划是将Psyco中实现的技术移植到PyPy。PyPy将使我们能够构建更灵活的JIT专业化工具,使其更容易进行实验,而又无需与开发过程保持同步Python语言。” psyco.sourceforge.net/introduction.html
igouy 2010年

1
@ jase21-“使python代码比C计数器部分运行得更快”-我们是否应该相信您的意思?
igouy

3
答案中的链接已损坏。
Basilevs

11

在某些情况下,编译与解释可能会有所帮助,但从技术角度讲,这是错误的二分法。

编译器(广义上)是翻译器。它将程序A转换为程序B,并在将来使用机器M执行。

解释员(广义上)是执行者。它是执行程序A的机器M。尽管我们通常从此定义中排除物理机器(或行为与物理机器相似的非物理机器)。但是从理论上讲,这种区分有些武断。


例如,以re.compile。它将正则表达式“编译”为中间形式,并且解释/评估/执行该中间形式。


最后,这取决于您在说什么级别的抽象以及您关心的是什么。人们说“已编译”或“解释”是对该过程中最有趣的部分的广义描述,但实际上,大多数程序都是以一种或另一种方式进行编译(翻译)和解释(执行)的。

CPython(Python语言最流行的实现)对于执行代码最为有趣。因此,通常将CPython描述为解释型。虽然这是一个宽松的标签。


7

虚拟机代码是原始源代码(字节代码)的更紧凑版本。由于它不是机器代码,因此仍需要由虚拟机解释。但是,与人类编写的原始代码相比,它更容易解析。

某些虚拟机会在首次解释虚拟机代码时生成机器代码(只是及时编译-JIT)。以下调用将直接使用此机器代码,从而加快执行速度。

据我所知,Ruby> = 1.9也使用类似Python的虚拟机。


5

Python运行时在虚拟机上运行自定义对象代码(字节码)。

编译过程将源代码转换为目标代码。

为了加快处理速度,目标代码(或字节代码,如果您愿意)存储在磁盘上,以便下次运行程序时可以重用它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.