我有以下代码
In [4]: def foo():
...: a = 2
...: b = 3
...: return a + b
...:
...:
In [5]: import dis
In [6]: dis.dis(foo)
2 0 LOAD_CONST 1 (2)
2 STORE_FAST 0 (a)
3 4 LOAD_CONST 2 (3)
6 STORE_FAST 1 (b)
4 8 LOAD_FAST 0 (a)
10 LOAD_FAST 1 (b)
12 BINARY_ADD
14 RETURN_VALUE
参考字节码:
我知道:
第一列是行号:2、3、4
第三列是操作名称:LOAD_CONST等
第五列是代码:(2)(a)
第二列怎么样:0、2、4、6、8 ...
第四列1、0、2、1
能否请您提供提示以找到相关信息?
答案 0 :(得分:1)
第二列是字节码字节索引;每个字节码由2个字节组成(一个字节指示确切的操作码,另一个字节指示操作码参数值)。实际上是第4列;您的输出中有两列没有当前值。
对于您的函数,您可以找到包含字节码的字节串作为__code__.co_code
属性:
>>> foo.__code__.co_code
b'd\x01}\x00d\x02}\x01|\x00|\x01\x17\x00S\x00'
所以b'd\x01'
是LOAD_CONST 1
,b'}\x00'
是STORE_FAST 0
,等等。
这记录在dis.disco()
function下:
输出分为以下几列:
- 行号,用于每行的第一条指令
- 当前指令,表示为
-->
- 带标签的指令,用
>>
表示,- 指令的地址
- 操作代码名称
- 操作参数和
- 括号中参数的解释。
使用dis.dis()
时,第2列(当前指令)将始终为空。
第3列(带标签的指令)在有循环或测试时使用。例如:
>>> dis.dis('if foo:\n for i in it:\n print(i)\nelse: print(bar)')
1 0 LOAD_NAME 0 (foo)
2 POP_JUMP_IF_FALSE 28
2 4 SETUP_LOOP 30 (to 36)
6 LOAD_NAME 1 (it)
8 GET_ITER
>> 10 FOR_ITER 12 (to 24)
12 STORE_NAME 2 (i)
3 14 LOAD_NAME 3 (print)
16 LOAD_NAME 2 (i)
18 CALL_FUNCTION 1
20 POP_TOP
22 JUMP_ABSOLUTE 10
>> 24 POP_BLOCK
26 JUMP_FORWARD 8 (to 36)
4 >> 28 LOAD_NAME 3 (print)
30 LOAD_NAME 4 (bar)
32 CALL_FUNCTION 1
34 POP_TOP
>> 36 LOAD_CONST 0 (None)
38 RETURN_VALUE
有4个跳转目标,其中几个操作码可以触发跳转到那些位置之一。它们充当视觉标记,使阅读更加轻松。