Python常见字节码

Python字节码

虽然python作为解释型语言,但是其也不是直接对源码进行解释

python解释器会将源码处理成字节码后,再借助python解释器运行程序

通过python自带的dis包可以将目标函数转化为字节码

例如:

1
2
3
4
5
6
7
8
9
10
import dis

def fun(x,y,z):
a = 1
a += 1
print("aaa")
fun(1,2,3)
return

dis.dis(fun)

得到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 46           0 LOAD_CONST               1 (1)
2 STORE_FAST 3 (a)

47 4 LOAD_FAST 3 (a)
6 LOAD_CONST 1 (1)
8 INPLACE_ADD
10 STORE_FAST 3 (a)

48 12 LOAD_GLOBAL 0 (print)
14 LOAD_CONST 2 ('aaa')
16 CALL_FUNCTION 1
18 POP_TOP

49 20 LOAD_GLOBAL 1 (fun)
22 LOAD_CONST 1 (1)
24 LOAD_CONST 3 (2)
26 LOAD_CONST 4 (3)
28 CALL_FUNCTION 3
30 POP_TOP

50 32 LOAD_CONST 0 (None)
34 RETURN_VALUE

进程已结束,退出代码0

常见指令

一般指令与一元操作指令

指令 作用
NOP 无作用,用于占位
POP_TOP 弹出栈顶元素
LOAD_CONST 将读取的值推入栈
LOAD_GLOBAL 将全局变量压入栈
STORE_FAST 将栈顶指令存入对应的局部变量
COMPARE_OP 比较操作符
CALL_FUNCTION 调用函数
BUILD_SLICE 调用切片,跟的参数为切片的值的个数一般上到下为[Val1:Val2:Val3]
JUMP_ABSOLUTE 向下跳转几句操作符,变量为跳转偏移量
UNARY_POSITIVE 实现Val1 = +Val1
UNARY_NEGATIVE 实现Val1 = -Val1
UNARY_NOT 实现Val1 = not Val1
UNARY_INVERT 实现Val1 = ~Val1
FOR_ITER for循环
GET_ITER 获取迭代器(一般后面跟循环)
GET_YIELD_FROM_ITER 获取yield生成器

二元操作指令

指令 作用
BINARY_POWER 乘方,栈顶为指数
BINARY_MULTIPLY 乘法
BINARY_MATRIX_MULTIPLY 矩阵乘法,3.5引入的新功能
BINARY_FLOOR_DIVIDE 除法,向下取整
BINARY_TRUE_DIVIDE 除法
BINARY_MODULO 取余
BINARY_ADD 加法
BINARY_SUBTRACT 减法
BINARY_SUBSCR 数组取下标,栈顶为下标
BINARY_LSHIFT 左移操作符
BINARY_RSHIFT 右移操作符(除二向下取整)
BINARY_AND 按位与
BINARY_XOR 异或
BINARY_OR 按位或
STORE_SUBSCR 列表下标存储,如Val1[Val2] = Val3
DELETE_SUBSCR 列表下标存储,如del Val1[Val2]
  • 自身操作指令,类似b += 1,就是上面有BINARY的指令将BINARY改为INPLACE

    其他指令见官方文档