Python解释,或编译,或两者?
从我的理解:
解释型语言是一种高级语言,由移动装置(一种将高级语言转换为机器码然后执行的程序)执行并执行; 它一次处理程序一点点。
编译语言是一种高级语言,其代码首先由编译器(将高级语言转换为机器码的程序)转换为机器码,然后由执行器(用于运行代码的另一程序)执行。
纠正我,如果我的定义是错误的。
现在回到Python,我有点困惑。 你到处学习Python是一种解释型语言,但是它被解释为一些中间代码(比如字节代码或者IL),而不是机器代码。 那么哪个程序执行IM代码呢? 请帮我理解Python脚本是如何处理和运行的。
首先,解释/编译不是语言的属性,而是实现的属性。 对于大多数语言来说,如果不是所有的实现都落在一个类别中,那么可以省略一些说语言被解释/编译的词语,但它仍然是一个重要的区别,因为它有助于理解,并且因为有相当多的语言与两种可用的实现(主要在function语言的领域,见Haskell和ML)。 另外,还有C解释器和项目,试图将Python的一个子集编译成C或C ++代码(以及随后的机器代码)。
其次,编译不限于提前编译为本机机器码。 编译器更一般地说是一种程序,它将一种编程语言中的程序转换成另一种编程语言中的程序(可以说,如果应用了重要的转换,甚至可以使用相同的input和输出语言编译器)。 JIT编译器可以在运行时编译为本地机器代码,这可以使编译速度非常接近甚至比编译之前更好(取决于比较的基准和质量)。
但是,要停止挑剔,并回答你要问的问题:实际上(阅读:使用一个有点stream行和成熟的实现),Python被编译 。 没有提前编译成机器码(即受限制和错误的“编译”,但是通常的定义),“只”编译成字节码 ,但它仍然是编译至less一些好处。 例如,语句a = bc()
被编译成字节stream,当“反汇编”时,看起来有点像load 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a)
load 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a)
load 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a)
。 这是一个简化,它实际上较less可读性和一点点低级别 – 您可以尝试使用标准库dis
模块 ,看看真正的交易看起来像什么。 解释这个比从更高层次的表示解释要快。
该字节码要么被解释(注意,在理论上和实际性能上,直接解释和首先编译到一些中间表示和解释它们之间是有区别的),与参考实现(CPython)一样,或者解释和编译为运行时优化的机器代码,就像PyPy一样 。
CPU只能理解机器码。 对于解释程序,解释器的最终目标是将程序代码“解释”为机器代码。 然而,通常现代的解释性语言不直接解释人类的代码,因为它太低效了。
Python解释器首先读取人类代码,并在将其解释为机器代码之前将其优化为一些立即代码。 这就是为什么你总是需要另一个程序来运行Python脚本,而不像C ++那样,你可以直接运行可执行文件。 例如c:\ Python27 \ python.exe或/ usr / bin / python。
答案取决于正在使用的Python的实现。 如果你正在使用可以说CPython (标准实现的Python)或Jython (针对与Java编程语言的集成),它是第一次翻译成字节码 ,并根据您使用这个Bycode的Python的实施是直接相应的虚拟机器的解释 。 用于CPython的PVM (Python虚拟机)和用于Jython的JVM (Java虚拟机)。
但让我们说你正在使用PyPy这是另一个标准的CPython实现。 它将使用一个即时编译器 。
几乎可以说,Python是解释型语言。 但是我们正在使用python的一次性编译过程的一部分来将完整的源代码转换成像java语言的字节码。
根据python.org它是一个解释器。
https://www.python.org/doc/essays/blurb/
Python是一种解释性的,面向对象的高级编程语言。
…
由于没有编译步骤
…
Python解释器和广泛的标准库可用…
…
相反,当解释器发现错误时,会引发exception。 当程序没有捕获exception时,解释器打印一个堆栈跟踪。
你编写的python代码被编译成python字节码,它创build扩展名为.pyc的文件。 如果编译,再次问题是,为什么不编译语言。
请注意,这不是传统意义上的汇编。 通常情况下,我们会说编译采用高级语言并将其转换为机器码。 但这是一个汇编。 编译成中间代码不是机器代码(希望你现在得到它)。
回到执行过程,在编译步骤中创build的pyc文件中存在的字节码将由适当的虚拟机执行,在我们的例子中,CPython VM使用时间戳(称为幻数)来validation是否。 py文件是否改变,取决于新build立的pyc文件。 如果pyc是当前代码,那么它只是跳过编译步骤。