Python使用dis模块把Python反编译为字节码的用法详解
dis ― Disassembler for Python bytecode,即把python代码反汇编为字节码指令. python -m dis xxx.py Python 代码是先被编译为字节码后,再由Python虚拟机来执行字节码, Python的字节码是一种类似汇编指令的中间语言, 一个Python语句会对应若干字节码指令,虚拟机一条一条执行字节码指令, 从而完成程序执行。 #coding=utf-8 while 1: pass while True: pass 下面是使用dis来进行剖析. E:&;python -m dis test_while.py 2 0 SETUP_LOOP 3 (to 6) 3 >> 3 JUMP_ABSOLUTE 3 5 >> 6 SETUP_LOOP 10 (to 19) >> 9 LOAD_NAME 0 (True) 12 POP_JUMP_IF_FALSE 18 可以看到,在while 1这里(第3行),直接是JUMP_ABSOLUTE指令; 再来看个小例子,先来一小段代码: In[6]: def test(): ... x = 1 ... if x < 3: ... return "yes" ... else: ... return "no" 代码执行后会输出: In[7]: import dis In[8]: dis.dis(test) 2 0 LOAD_CONST 1 (1) 3 STORE_FAST 0 (x) 3 6 LOAD_FAST 0 (x) 9 LOAD_CONST 2 (3) 12 COMPARE_OP 0 (<) 15 POP_JUMP_IF_FALSE 22 4 18 LOAD_CONST 3 ('yes') 21 RETURN_VALUE 6 >> 22 LOAD_CONST 4 ('no') 25 RETURN_VALUE 26 LOAD_CONST 0 (None) 29 RETURN_VALUE以第一条指令为例, 第一列的数字(2)表示对应源代码的行数。第二列的数字是字节码的索引,指令LOAD_CONST在0位置。第三列是指令本身对应的人类可读的名字。第四列表示指令的参数。第5列则是计算后的实际参数。其中的“>>" 表示跳转的目标, 第4列的“22” 表明了跳转到索引为22的指令。Python代码在编译过程中会生成CodeObject,CodeObject是在虚拟机中的抽象表示, 在Python C源码中表示为PyCodeObject, 而生成的.pyc 文件则是字节码在磁盘中的表现形式。 以Python代码为讲,test.__code__.co_code 表示test函数的字节码指令序列。 将此序列打印出来, code = [ord(i) for i in list(test.__code__.co_code)] print code 输出: 复制代码 代码如下: [100,1,125,124,100,2,107,114,22,3,83,4,83] 对照dis输出的字节码指令, 以[100,1,0]序列为例。100表示在Python字节码定义中的索引,在python代码中, (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |