如何读取python字节码?

2024-04-29 20:06:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我很难理解Python的字节码及其dis模块。

import dis
def func():
   x = 1
dis.dis(func)

当在解释器中键入上述代码时,将生成以下输出:

    0 LOAD_CONST                  1(1)
    3 STORE_FAST                  0(x)
    6 LOAD_CONST                  0(NONE)
    9 RETURN_VALUE

例如:

什么是LOAD_CONSTSTORE_FAST0369这样的数字?

一个具体的资源,在那里我可以找到这个信息将非常感谢。


Tags: 模块store代码importnone键入return字节
1条回答
网友
1楼 · 发布于 2024-04-29 20:06:25

字节码之前的数字偏移到原始二进制字节码中:

>>> func.__code__.co_code
'd\x01\x00}\x00\x00d\x00\x00S'

有些字节码带有影响每个字节码工作方式的附加信息(参数),偏移量告诉您字节码在字节流中的位置。

例如,LOAD_CONST字节码(ASCIId,hex 64)后面跟着两个额外的字节,这些字节编码对与字节码关联的常量的引用。结果,在索引3处找到了STORE_FAST操作码(ASCII},hex 7D)。

^{} module documentation列出了每条指令的含义。对于LOAD_CONST,它说:

Pushes co_consts[consti] onto the stack.

它引用始终与代码对象一起存在的co_consts结构;编译器构造如下:

>>> func.__code__.co_consts
(None, 1)

操作码从该结构加载索引1(字节码中的01 00字节编码为1),并且dis已经为您查找过了;它是值1

下一条指令^{}描述为:

Stores TOS into the local co_varnames[var_num].

这里,TOS指的是堆栈的顶部;注意,LOAD_CONST只是东西推到堆栈上,即1值。co_varnames是另一个结构;它引用本地变量名,操作码引用索引0:

>>> func.__code__.co_varnames
('x',)

dis也查过了,您在代码中使用的名称是x。因此,这个操作码将1存储到x

另一个LOAD_CONSTNone从索引0加载到堆栈上,然后是^{}

Returns with TOS to the caller of the function.

所以这个指令取堆栈的顶部(带有None常量)并从这个代码块返回。None是没有显式return语句的函数的默认返回值。

您在dis输出中省略了一些内容,行号是:

>>> dis.dis(func)
  2           0 LOAD_CONST               1 (1)
              3 STORE_FAST               0 (x)
              6 LOAD_CONST               0 (None)
              9 RETURN_VALUE        

注意第一行的2;这是原始源代码中的行号,其中包含用于这些指令的Python代码。Python代码对象具有co_lnotabco_firstlineno属性,这些属性允许您将字节码映射回原始源代码中的行号。dis在显示反汇编时为您执行此操作。

相关问题 更多 >