本文最后更新于:2022年7月4日 上午
查看字节码可以帮助我们更好的理解python的执行流程,本文记录 python 生成函数字节码的方法。
简介
- 既然叫“字节码”,这些操作码自然是以字节为单位的咯,于是最多只能表示256个不同的操作码。Python实际上只用了百来个操作码。
- 操作码小于90的为无参数的,指令仅包含操作码自身,共1字节;大于等于90的,则每条指令在操作码之后还带有1个参数,参数长度为2字节,共3字节。
- Python程序的字节码在运行时以PyStringObject的形式保存在PyCodeObject的co_code域里。co_code域只含有指令而不包含别的程序数据;变量名、常量等数据均放在别的域里。
- Python的字节码指令集是基于栈的指令集。这里说的“栈”不是指函数调用栈,而是指专门用于求值的栈,可以称为“求值栈”(evaluation stack)或者“操作数栈”(operand stack)。求值过程的临时变量都放在求值栈上,指令集中的大部分都是与栈打交道。
实现方法
查看模块中所有函数和所有类中的函数字节码
1 2
| import dis,target dis.dis(target)
|
查看模块中某函数或类中某函数生成的字节码:
1 2
| import dis,target dis.dis(target.funcA)
|
或
1 2
| import dis,target dis.dis(target.classA)
|
查看函数外的操作:
1 2 3 4 5
| import dis s=open('target.py').read() co=compile(s,'target.py','exec')
dis.dis(co)
|
示例
1 2 3 4 5 6 7 8 9
| import dis
def hello(x, y): t = x ** 2 s = y ** 0.5 r = t + s return r
dis.dis(hello)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 4 0 LOAD_FAST 0 (x) 2 LOAD_CONST 1 (2) 4 BINARY_POWER 6 STORE_FAST 2 (t)
5 8 LOAD_FAST 1 (y) 10 LOAD_CONST 2 (0.5) 12 BINARY_POWER 14 STORE_FAST 3 (s)
6 16 LOAD_FAST 2 (t) 18 LOAD_FAST 3 (s) 20 BINARY_ADD 22 STORE_FAST 4 (r)
7 24 LOAD_FAST 4 (r) 26 RETURN_VALUE
|
参考资料