栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Python编译/解释过程

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python编译/解释过程

除非您使用某些特殊的实现(例如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)  10 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_FAST0
从而从保存参数的任何地方获取参数0(
n
传递给
fib
),并将其压入解释器的堆栈(Python的解释器是堆栈计算机)。在阅读下一条说明时,
LOAD_CONST1
,它将从该函数拥有的常量集合中获取一个常量1(在这种情况下恰好是2),并将其压入堆栈。您实际上可以看到以下常量:

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

下一条指令,

COMPARE_OP0
告诉解释器弹出两个最顶部的堆栈元素,并在它们之间进行不等式比较,将布尔结果推回堆栈。第四条指令基于布尔值确定是向前跳五条指令还是继续下一条指令。所有这些动词都解释
ifn <2
了条件表达式中的部分
fib
。弄清楚其余
fib
字节码的含义和行为,对您而言将是非常有启发性的练习。唯一的一个,我不知道的是
POP_TOP
,我猜想
JUMP_IF_FALSE
已定义为将其布尔参数保留在堆栈上而不是将其弹出,因此必须显式弹出它。

更具指导意义的是检查原始字节码,

fib
从而:

>>> pre = fib.func_pre.co_pre>>> pre'|x00x00dx01x00jx00x00ox05x00x01|x00x00Sx01tx00x00|x00x00dx01x00x18x83x01x00tx00x00|x00x00dx02x00x18x83x01x00x17S'>>> import oppre>>> op = pre[0]>>> op'|'>>> op = ord(op)>>> op124>>> oppre.opname[op]'LOAD_FAST'>>>

因此,您可以看到字节码的第一个字节是

LOAD_FAST
指令。下一对字节
'x00x00'
(16位中的数字0)是的参数
LOAD_FAST
,并告诉字节码解释器将参数0加载到堆栈上。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/610512.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号