gpt4 book ai didi

Python编译/解释过程

转载 作者:IT老高 更新时间:2023-10-28 21:35:29 26 4
gpt4 key购买 nike

我正在尝试更清楚地了解 python 编译器/解释器过程。不幸的是,我没有上过解释课,也没有读过很多关于解释的文章。

基本上,我现在的理解是,来自 .py 文件的 Python 代码首先被编译成 python 字节码(我假设是我偶尔看到的 .pyc 文件?)。接下来,字节码被编译成机器码,一种处理器真正理解的语言。差不多,我读过这个帖子 Why python compile the source to bytecode before interpreting?

请记住,我对编译器/解释器的了解几乎不存在,有人能给我一个很好的解释吗?或者,如果这不可能,也许可以给我一些资源,让我快速了解编译器/解释器?

谢谢

最佳答案

字节码实际上并没有被解释为机器码,除非你使用了一些特殊的实现,比如 pypy。

除此之外,您的描述正确。字节码被加载到 Python 运行时并由虚拟机解释,虚拟机是一段代码,读取字节码中的每条指令并执行指示的任何操作。您可以使用 dis 查看此字节码模块,如下:

>>> def fib(n): return n if n < 2 else fib(n - 2) + fib(n - 1)
...
>>> fib(10)
55
>>> import dis
>>> dis.dis(fib)
1 0 LOAD_FAST 0 (n)
3 LOAD_CONST 1 (2)
6 COMPARE_OP 0 (<)
9 JUMP_IF_FALSE 5 (to 17)
12 POP_TOP
13 LOAD_FAST 0 (n)
16 RETURN_VALUE
>> 17 POP_TOP
18 LOAD_GLOBAL 0 (fib)
21 LOAD_FAST 0 (n)
24 LOAD_CONST 1 (2)
27 BINARY_SUBTRACT
28 CALL_FUNCTION 1
31 LOAD_GLOBAL 0 (fib)
34 LOAD_FAST 0 (n)
37 LOAD_CONST 2 (1)
40 BINARY_SUBTRACT
41 CALL_FUNCTION 1
44 BINARY_ADD
45 RETURN_VALUE
>>>

详细解释

理解上面的代码永远不会被你的 CPU 执行是非常重要的;它也没有被转换成某种东西(至少,不是在 Python 的官方 C 实现中)。 CPU 执行虚拟机代码,虚拟机代码执行字节码指令指示的工作。当解释器想要执行 fib函数,它一次读取一个指令,然后按照指令执行。它查看第一条指令,LOAD_FAST 0 , 从而从保存参数的任何位置获取参数 0(传递给 nfib )并将其推送到解释器的堆栈(Python 的解释器是堆栈机器)。在阅读下一条指令时,LOAD_CONST 1 ,它从函数拥有的常量集合中获取常量 1,在这种情况下恰好是数字 2,并将其压入堆栈。您实际上可以看到这些常量:

>>> fib.func_code.co_consts
(None, 2, 1)

下一条指令,COMPARE_OP 0 , 告诉解释器弹出两个最顶层的堆栈元素并在它们之间执行不等式比较,将 bool 结果推回堆栈。第四条指令根据 bool 值确定是向前跳转五条指令还是继续下一条指令。所有这些花言巧语都解释了 if n < 2 fib 中的条件表达式的一部分.这将是一个非常有指导意义的练习,可以让您梳理出 fib 其余部分的含义和行为。字节码。唯一一个,我不确定是POP_TOP ;我猜JUMP_IF_FALSE被定义为将其 bool 参数留在堆栈上而不是弹出它,因此必须显式弹出它。

更有意义的是检查 fib 的原始字节码因此:

>>> code = fib.func_code.co_code
>>> code
'|\x00\x00d\x01\x00j\x00\x00o\x05\x00\x01|\x00\x00S\x01t\x00\x00|\x00\x00d\x01\x00\x18\x83\x01\x00t\x00\x00|\x00\x00d\x02\x00\x18\x83\x01\x00\x17S'
>>> import opcode
>>> op = code[0]
>>> op
'|'
>>> op = ord(op)
>>> op
124
>>> opcode.opname[op]
'LOAD_FAST'
>>>

因此您可以看到字节码的第一个字节是LOAD_FAST操作说明。下一对字节,'\x00\x00' (16 位中的数字 0)是 LOAD_FAST 的参数, 并告诉字节码解释器将参数 0 加载到堆栈中。

关于Python编译/解释过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3299648/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com