[英]Python interpretation model in comparison to direct and virtual machine compilation
我一直在编译图表 (双关语),希望了解常见编程语言的不同实现。 我了解代码是编译还是解释取决于代码的实现,而不是编程语言本身的一个方面。
我有兴趣将Python解释与直接编译(C ++之前的版本)进行比较
和虚拟机模型(例如Java或C#)
根据上面的两个图表,能否请您帮我制定一个类似的流程图,说明如何将.py文件转换为.pyc,使用标准库(我收集它们称为模块)然后真正运行。 SO上的许多程序员表示python作为脚本语言不是由CPU执行,而是由解释器执行,但这听起来是不可能的,因为最终硬件必须进行计算。
首先,这是一个实现细节。 我将答案限于CPython和PyPy,因为我对它们很熟悉。 对于Jython,IronPython和其他实现的答案将有所不同-可能根本不同。
Python更接近“虚拟机模型”。 Python代码与某些知识水平过高的人相反,尽管所有人(包括我在内)在不经意的讨论中将其混为一谈,但从未进行过解释。 始终在加载时将其编译为字节码(同样在CPython和PyPy上)。 如果由于导入模块和从.py文件加载而加载了该文件,则可能会创建一个.pyc文件来缓存编译输出。 此步骤不是必须的; 您可以通过各种方式将其关闭,并且程序执行不会影响最小的位(除非下一个加载模块的过程必须再次执行该操作)。 但是,编译为字节码是不可避免的,如果未从磁盘加载字节码,则会在内存中生成该字节码。
然后在模块级别执行此字节码(其确切细节是实现细节,并且在版本之间有所不同),这需要构建函数对象,类对象等。 这些对象只是简单地重用(指向指针)已在内存中的字节码。 这与C ++和Java不同,在C ++和Java中,代码和类在编译期间/之后固定设置。 在执行过程中,可能会遇到import
语句。 我没有足够的时间,空间和理解来描述进口机器,但简短的故事是:
sys
就是这样一个模块。 某些Python代码也可能事先运行,特别是在您启动交互式解释器时(查找site.py
)。 所有这些都适用于标准库模块以及第三方模块。 这就是为什么如果您调用自己的脚本就像在该脚本中导入的标准库模块一样调用它会收到一个令人困惑的错误消息的原因(该脚本本身会导入,尽管不会由于缓存而崩溃-这是我提到的许多事情之一)。
字节码的执行方式(问题的最后一部分)有所不同。 CPython只是对其进行解释,但是正如您正确地指出的那样,这并不意味着它神奇地没有使用CPU。 取而代之的是,有一个大的丑陋循环,该循环检测接下来应执行哪些字节码指令,然后跳转到执行该指令语义的某些本地代码。 PyPy更有趣; 它从解释开始,但会记录一些统计信息。 当它决定值得这样做时,它开始详细记录解释器的操作,并生成一些高度优化的本机代码。 解释器仍用于Python代码的其他部分。 请注意,对于许多JVM和可能的.NET来说都是相同的,但是您引用的图对此有所掩饰。
从技术上讲,Python是一种脚本语言,但它也是经过编译的,从其源文件中提取python源并将其输入到解释器中,该解释器通常将源编译为内部字节码,然后将其丢弃或从外部丢弃,并将其保存为.pyc格式。
是的,python是单个虚拟机,然后位于实际硬件之上,但是所有python字节码都是pvm(Python虚拟机)的一系列指令,与实际CPU的汇编程序非常相似。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.