繁体   English   中英

与直接和虚拟机编译相比的Python解释模型

[英]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语句。 我没有足够的时间,空间和理解来描述进口机器,但简短的故事是:

  • 如果已经导入一次,则将获得该模块对象(静态语言仅在编译时才具有的另一种运行时构造)。 在运行任何Python代码之前,已经导入了几个内置模块(好吧,出于PyPy的原因,所有这些模块都在PyPy中),这仅仅是因为它们与解释器的核心紧密集成并且非常基础。 sys就是这样一个模块。 某些Python代码也可能事先运行,特别是在您启动交互式解释器时(查找site.py )。
  • 否则,找到模块。 规则与我们无关。 最后,这些规则到达Python文件或动态链接的机器代码段(在Windows上为.DLL,尽管Python模块专门使用扩展名.pyd,但这仅是名称;在Unix上使用等效的.so )。
    • 首先将模块加载到内存中(动态加载或解析并编译为字节码)。
    • 然后,初始化模块。 扩展模块具有一种特殊的功能,即所谓的功能。 简单地从上至下运行Python模块。 在行为良好的模块中,这只是设置全局数据,定义函数和类以及导入依赖项。 当然,其他任何事情也可能发生。 生成的模块对象将被缓存(记住步骤一)并返回。

所有这些都适用于标准库模块以及第三方模块。 这就是为什么如果您调用自己的脚本就像在该脚本中导入的标准库模块一样调用它会收到一个令人困惑的错误消息的原因(该脚本本身会导入,尽管不会由于缓存而崩溃-这是我提到的许多事情之一)。

字节码的执行方式(问题的最后一部分)有所不同。 CPython只是对其进行解释,但是正如您正确地指出的那样,这并不意味着它神奇地没有使用CPU。 取而代之的是,有一个大的丑陋循环,该循环检测接下来应执行哪些字节码指令,然后跳转到执行该指令语义的某些本地代码。 PyPy更有趣; 它从解释开始,但会记录一些统计信息。 当它决定值得这样做时,它开始详细记录解释器的操作,并生成一些高度优化的本机代码。 解释器仍用于Python代码的其他部分。 请注意,对于许多JVM和可能的.NET来说都是相同的,但是您引用的图对此有所掩饰。

对于python的参考实现:

(.py)-> python(检查.pyc)->(.pyc)-> python(执行动态加载模块)

还有其他实现 最值得注意的是:

  • jython将(.py)编译为(.class),并从那里遵循Java模式
  • pypy ,它使用JIT进行编译(.py)。 那里的链可能会有所不同(pypy可以在cpython,jython或.net环境中运行)

从技术上讲,Python是一种脚本语言,但它也是经过编译的,从其源文件中提取python源并将其输入到解释器中,该解释器通常将源编译为内部字节码,然后将其丢弃或从外部丢弃,并将其保存为.pyc格式。

是的,python是单个虚拟机,然后位于实际硬件之上,但是所有python字节码都是pvm(Python虚拟机)的一系列指令,与实际CPU的汇编程序非常相似。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM