每次运行函数时会创建一个frame,在frame环境下一条一条的运行python的字节码bytecode。frame是以栈为基础运行的,字节码或者从栈中弹出数据进行运算或者把数据添加到栈中。
code object
每个函数都有一个code object,函数的__code__属性可以获得函数的code object
- co_argcount: 参数数量,不包含变长参数和仅关键字参数
- co_posonlyargcount: 仅限位置参数的数量
- co_kwonlyargcount: 仅限关键字参数的数量,不包含**参数
- co_code: 字符串形式的原始字节码
def func(a, b=1, /, *, c):
pass
code_obj = func.__code__
print(code_obj.co_code) # 字节码字符串 b'd/x00S/x00'
print(code_obj.co_argcount) # 参数数量 2
print(code_obj.co_posonlyargcount) # 必须位置参数数量 2
print(code_obj.co_kwonlyargcount) # 必须关键字参数数量 1
import dis
dis.dis(code_obj.co_code)
# 0 LOAD_CONST 0 (0)
# 2 RETURN_VALUE
- co_name: 函数名
- co_filename: 文件名
- co_lnotab: 代码行数和对应字节码的映射
print(code_obj.co_name) # func
print(code_obj.co_filename) # xx.py
print(code_obj.co_lnotab) # b'/x00/x01'
- co_flags: 一个bitmap,标识函数是否有些特殊情况,比如变长参数或者生成器函数
- co_stacksize: 需要的虚拟机堆栈空间
print(code_obj.co_flags) # 67
print(code_obj.co_stacksize) # 1
- co_cellvars:被其他作用域范围引用的变量
- co_freevars:引用的外部变量,函数闭包引用
- co_nlocals: 局部变量数
- co_varnames: 参数名和局部变量的元组
- co_names: 除了varname,freevar,cellvar之外的name
- co_consts: 常量元组,None常驻
import dis
def print_var(cobj):
print(f"n locals: {cobj.co_nlocals}")
print(f"varnames: {cobj.co_varnames}")
print(f"cellvars: {cobj.co_cellvars}")
print(f"freevars: {cobj.co_freevars}")
print(f"names : {cobj.co_names}")
print(f"consts : {cobj.co_consts}")
class A:
attr= 'class A'
def A_f():
pass
def g():
x = 1
dic = {}
a = A()
a.attr="B"
def f():
y=3
dic['x']=1
return f
g_code = g.__code__
f_code = g().__code__
dis.dis(g_code.co_code)
print_var(g_code)
print()
dis.dis(f_code.co_code)
print_var(f_code)
"""
0 LOAD_CONST 1 (1)
2 STORE_FAST 0 (0)
4 BUILD_MAP 0
6 STORE_DEREF 0 (0)
8 LOAD_GLOBAL 0 (0)
10 CALL_FUNCTION 0
12 STORE_FAST 1 (1)
14 LOAD_CONST 2 (2)
16 LOAD_FAST 1 (1)
18 STORE_ATTR 1 (1)
20 LOAD_CLOSURE 0 (0)
22 BUILD_TUPLE 1
24 LOAD_CONST 3 (3)
26 LOAD_CONST 4 (4)
28 MAKE_FUNCTION 8 (closure)
30 STORE_FAST 2 (2)
32 LOAD_FAST 2 (2)
34 RETURN_VALUE
n locals: 3
varnames: ('x', 'a', 'f') 局部变量名
cellvars: ('dic',) # dic被内部函数引用
freevars: ()
names : ('A', 'attr') # 其他名
consts : (None, 1, 'B', <code object f at 0x000001BFB302F7C0, file "d:/LinuxCcpp/web_framework/�½��ļ���/f_code_.py", line 42>, 'g.<locals>.f')
0 LOAD_CONST 1 (1)
2 STORE_FAST 0 (0)
4 LOAD_CONST 2 (2)
6 LOAD_DEREF 0 (0)
8 LOAD_CONST 3 (3)
10 STORE_SUBSCR
12 LOAD_CONST 0 (0)
14 RETURN_VALUE
n locals: 1
varnames: ('y',)
cellvars: ()
freevars: ('dic',) # 闭包引用的外部变量
names : ()
consts : (None, 3, 1, 'x')
"""
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/279091.html