如何读取python字节码?

Pra*_*hal 17 python bytecode python-2.7

我在理解Python的字节码及其dis模块时遇到了很多困难.

import dis
def func():
   x = 1
dis.dis(func)
Run Code Online (Sandbox Code Playgroud)

在解释器中输入上面的代码会产生以下输出:

    0 LOAD_CONST                  1(1)
    3 STORE_FAST                  0(x)
    6 LOAD_CONST                  0(NONE)
    9 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)

例如:

是什么意思LOAD_CONST,STORE_FAST和喜欢的数字0,3,69

我将非常感谢您可以找到此信息的特定资源.

Mar*_*ers 36

字节码前面的数字是原始二进制字节码的偏移量:

>>> func.__code__.co_code
'd\x01\x00}\x00\x00d\x00\x00S'
Run Code Online (Sandbox Code Playgroud)

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

例如,LOAD_CONST字节码(ASCII d,十六进制64)之后是两个附加字节,用于编码对与字节码相关的常量的引用.结果,STORE_FAST操作码(ASCII },十六进制7D)在索引3处找到.

dis模块文件列出了每个指令的意思.因为LOAD_CONST,它说:

co_consts[consti]到堆栈上.

它指的co_consts是始终与代码对象一起出现的结构; 编译器构造:

>>> func.__code__.co_consts
(None, 1)
Run Code Online (Sandbox Code Playgroud)

操作码从该结构加载索引1(字节码中的01 00字节编码为1),并dis为您查找; 这是价值1.

下一条指令STORE_FAST描述为:

将TOS存入当地co_varnames[var_num].

这里TOS指的是Top Of Stack; 请注意,LOAD_CONST只是东西到了堆栈上,1值.co_varnames是另一种结构; 它引用局部变量名,操作码引用索引0:

>>> func.__code__.co_varnames
('x',)
Run Code Online (Sandbox Code Playgroud)

dis看起来也是这样,你在代码中使用的名字是x.因此,这个操作码存储1x.

另一个从索引0 LOAD_CONST加载None到堆栈,然后是RETURN_VALUE:

返回TOS到函数的调用者.

所以这条指令占据了堆栈的顶部(带有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        
Run Code Online (Sandbox Code Playgroud)

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