# PyCodeObj和PyFrameObj
# PyCodeObj和PyFrameObj
pycodeobj 在编译时创建,是静态的。
pyframeobj 在运行时创建,是动态的。一个 pycodeobj 可以对应多个 pyframeobj,每个 pyframeobj 都有一个对应的 pycodeobj。
pycodeobj 主要存储静态信息,例如:
- co_name # 对象名称 - co_argcount # 参数个数(非函数一般为0) - co_code # 字节码的序列化形式 - co_consts # 使用到的常量 - co_names # 使用到的名称 - co_nlocals # 局部变量个数 - co_varnames # 局部变量名称 - co_flags # 编译标志 - co_filename # 文件名 - co_firstlineno # 源代码第一行的行号 - co_freevars # 自由变量(未在局部绑定的变量) - co_cellvars # 单元变量(局部作用域但在内嵌函数中使用的变量)- 即闭包变量 - co_kwonlyargcount # 仅关键字参数的数量 - co_posonlyargcount # 仅位置参数的数量 - co_stacksize # 执行栈大小 - co_lnotab # 行号表 - co_linetable # 行号表 - co_positions # 字节码中的位置 - co_lines # 源代码行号 - co_qualname # 对象的限定名称 - co_exceptiontable # 异常表pyframeobj 用来存储运行时信息,例如:
- f_code # 关联的代码对象 - f_back # 调用此帧的帧 - 上一帧 - f_builtins # 内置名称空间 - f_globals # 全局名称空间 - f_locals # 局部名称空间 - f_lineno # 当前行号 - f_lasti # 最后执行的指令的索引 - f_trace # 跟踪函数 - f_exc_type # 当前异常类型 - f_exc_value # 当前异常值 - f_exc_traceback # 当前异常的追溯信息 - f_restricted # 是否为受限制的执行 - f_stacktop # 值栈的顶部 - f_valuestack # 值栈 - f_blockstack # 块栈 - f_localsplus # 局部变量和其它局部变量存储 - 实际就是运行时的栈
# 示例
"""
>>> text = open("./PyTests/codeobj_test1.py", 'r').read()
>>> text
's = "FFFFF"\n\ndef func(x, y):\n if x == y:\n return 0\n return 1\n\nclass F:\n pass\n\nfunc()\n\n\n'
>>> code = compile(text, 'cbt', 'exec')
>>> code
<code object <module> at 0x7ff04eaa2d20, file "cbt", line 1>
def print_code(co):
print(f'co_name:\t{co.co_name}')
for attr in dir(co):
if attr[0] != '_':
print(f' {attr}:\t{getattr(co,attr)}')
...
>>>
def dfs(co):
print_code(co)
for c in co.co_consts:
if isinstance(c, types.CodeType):
dfs(c)
...
>>>
>>> import types
>>> dfs(code)
co_name: <module>
co_argcount: 0
co_cellvars: ()
co_code: b'd\x00Z\x00d\x01d\x02\x84\x00Z\x01G\x00d\x03d\x04\x84\x00d\x04\x83\x02Z\x02e\x01\x83\x00\x01\x00d\x05S\x00'
co_consts: ('FFFFF', <code object func at 0x7ff04eaa2780, file "cbt", line 3>, 'func', <code object F at 0x7ff04eaa2c90, file "cbt", line 8>, 'F', None)
co_filename: cbt
co_firstlineno: 1
co_flags: 64
co_freevars: ()
co_kwonlyargcount: 0
co_lnotab: b'\x04\x02\x08\x05\x0e\x03'
co_name: <module>
co_names: ('s', 'func', 'F')
co_nlocals: 0
co_stacksize: 3
co_varnames: ()
co_name: func
co_argcount: 2
co_cellvars: ()
co_code: b'|\x00|\x01k\x02r\x0cd\x01S\x00d\x02S\x00'
co_consts: (None, 0, 1)
co_filename: cbt
co_firstlineno: 3
co_flags: 67
co_freevars: ()
co_kwonlyargcount: 0
co_lnotab: b'\x00\x01\x08\x01\x04\x01'
co_name: func
co_names: ()
co_nlocals: 2
co_stacksize: 2
co_varnames: ('x', 'y')
co_name: F
co_argcount: 0
co_cellvars: ()
co_code: b'e\x00Z\x01d\x00Z\x02d\x01S\x00'
co_consts: ('F', None)
co_filename: cbt
co_firstlineno: 8
co_flags: 64
co_freevars: ()
co_kwonlyargcount: 0
co_lnotab: b'\x08\x01'
co_name: F
co_names: ('__name__', '__module__', '__qualname__')
co_nlocals: 0
co_stacksize: 1
co_varnames: ()
"""