Code Object
# 每一个函数只会生成一个code object
import dis
def func(a, b):
return a * b
code = func.__code__
print(dis.dis(func))
# for dis doc: https://docs.python.org/3/library/dis.html
# 3 0 RESUME 0
# 4 2 LOAD_FAST 0 (a) # 取到stack顶, 这里0是co_varnames[0]
# 4 LOAD_FAST 1 (b) # 取到stack顶
# 6 BINARY_OP 5 (*) # stack顶两元素相加
# 10 RETURN_VALUE # 返回stack顶
# None
print(f'co_code: {code.co_code}') # 二进制code码
print(f'co_name: {code.co_name}') # 函数吗
print(f'co_filename: {code.co_filename}') # 所在文件名
print(f'co_lnotab: {code.co_lnotab}') # bytecode对应的源代码行数(二进制码)
print(f'co_flags: {code.co_flags}') # 控制PVM行为
print(f'co_stacksize: {code.co_stacksize}') # stacksize
print(f'co_argcount: {code.co_argcount}')
print(f'co_posonlyargcount: {code.co_posonlyargcount}') # positional only args
# 比如 f(a,b=3,/,*args,**kwargs) 这里前面两个必须positonal传
print(f'co_kwonlyargcount: {code.co_kwonlyargcount}') # keyword only args
# 比如 f(a,*,b=3,*args,**kwargs) 这里b必须keyword传
print(f'co_nlocals: {code.co_nlocals}') # allmost sizeof(co_varnames)
print(f'co_varnames: {code.co_varnames}') # 所有local var包括args
print(f'co_names: {code.co_names}') # 所有除了co_varnames/co_cellvars/co_freevars的
# 如 b = a.attr 这个 attr 放到c co_names 里
print(f'co_cellvars: {code.co_cellvars}') # variable还会在其他scope用到, 闭包相关
print(f'co_freevars: {code.co_freevars}') # variable从其他scope来, 闭包相关
print(f'co_consts: {code.co_consts}') # 函数出现的所有常量
Python Frame
# 和 code object 区别是记录当前func运行stack状态, 即栈机
# Frame 是一个栈结构,实现是用链表完成的
import inspect
from objprint import op
def func(a, b):
frame = inspect.currentframe()
op(frame, honor_existing=False, depth=2) # 打印
return a + b
func(1,2)
# 以下是输出
<frame 0x7f955ebb4110
.f_back = <frame 0x7f955dc69bc0 # 上一个frame(调用者所属的frame)
.f_back = None,
.f_builtins = { ... }, # 这个frame对应内置函数
.f_code = <code 0x7f955eb40f30 ... >, # code object
.f_globals = { ... }, # 全局变量
.f_lasti = 48, # program counter 指现在运行到哪个字节码了
.f_lineno = 10, # 现在运行到第几行了
.f_locals = { ... }, # 局部变量
.f_trace = None, # 如果不是None就有callback
.f_trace_lines = True, # 是否每行trigger callback
.f_trace_opcodes = False # 是否每个字节码trigger callback
>,