甚至我在理解CPython,JPython,IronPython,PyPy之间的区别时也遇到了相同的问题。
因此,在开始解释之前,我愿意清除三件事:
- Python:这是一门语言,它仅说明/描述如何向解释器(接受您的python代码的程序)传达/表达自己。
- 实现:一切都与解释器的编写方式有关,特别是关于哪种语言以及最终使用的语言。
- 字节码:它是由程序(通常称为虚拟机)而不是“真实”计算机(即硬件处理器)处理的代码。
CPython是用C语言编写的实现。它最终生成特定于Python的字节码(基于堆栈计算机的指令集),然后执行它。将Python代码转换为字节码的原因是,如果看起来像机器指令,则更容易实现解释器。但是,没有必要在执行Python代码之前产生一些字节码(但CPython确实会产生)。
如果您想查看CPython的字节码,则可以。方法如下:
>>> def f(x, y): # line 1
... print("Hello") # line 2
... if x: # line 3
... y += x # line 4
... print(x, y) # line 5
... return x+y # line 6
... # line 7
>>> import dis # line 8
>>> dis.dis(f) # line 9
2 0 LOAD_GLOBAL 0 (print)
2 LOAD_CONST 1 ('Hello')
4 CALL_FUNCTION 1
6 POP_TOP
3 8 LOAD_FAST 0 (x)
10 POP_JUMP_IF_FALSE 20
4 12 LOAD_FAST 1 (y)
14 LOAD_FAST 0 (x)
16 INPLACE_ADD
18 STORE_FAST 1 (y)
5 >> 20 LOAD_GLOBAL 0 (print)
22 LOAD_FAST 0 (x)
24 LOAD_FAST 1 (y)
26 CALL_FUNCTION 2
28 POP_TOP
6 30 LOAD_FAST 0 (x)
32 LOAD_FAST 1 (y)
34 BINARY_ADD
36 RETURN_VALUE
现在,让我们看一下上面的代码。第1至6行是功能定义。在第8行中,我们导入了“ dis”模块,该模块可用于查看由CPython(解释器)生成的中间Python字节码(或者可以说是Python字节码的反汇编程序)。
注意:我从#python IRC频道获得了此代码的链接:https ://gist.github.com/nedbat/e89fa710db0edfb9057dc8d18d979f9c
然后是Jython,它是用Java编写的,最终生成Java字节码。Java字节代码在Java运行时环境上运行,该环境是Java虚拟机(JVM)的实现。如果这令人困惑,那么我怀疑您不知道Java如何工作。用外行术语来说,Java编译器采用Java(语言,而不是编译器)代码,并输出只能使用JRE运行的文件(Java字节码)。这样做的目的是,一旦编译了Java代码,就可以将其以Java字节代码格式移植到其他计算机上,该格式只能由JRE运行。如果仍然令人困惑,那么您可能想看看该网页。
在这里,您可能会问CPython的字节码是否像Jython一样可移植,我怀疑不是。CPython实现中生成的字节码特定于该解释器,以便于进一步执行代码(我还怀疑,这种中间字节码的产生只是为了在许多其他解释器中简化处理)。
因此,在Jython中,当您编译Python代码时,最终会得到Java字节代码,该代码可以在JVM上运行。
同样,IronPython(用C#语言编写)将您的Python代码编译为公共语言运行时(CLR),与Microsoft开发的JVM相比,这项技术是类似的。