Python 数据模型之—— Code Object (代码对象)#
最近在代码厨房——开源松 Sprint 5 中认领了一个给 pydumpling 添加可视化调用栈的 PR, 而 pydumpling 所保存的 .dump 文件中包含了异常栈相关的信息,其中就包含 Python 代码对象 的相关内容。因此,我结合 Python 文档和 AI 工具,简单整理了一些相关内容。
点击查看文档: Python 代码对象官方文档
co_name#
表示函数或方法的名称。
例如,如果有一个函数 def foo():,那么 co_name 会返回字符串 "foo"。
co_qualname#
表示函数的完整限定名称。 它返回函数的 完全限定名,即包括模块和类(如果是类方法)路径的名称。
例如,如果一个函数定义在 mymodule 模块中的 MyClass 类下,co_qualname 会返回 "mymodule.MyClass.foo",即带有模块和类名的路径。
co_argcount#
表示函数的位置参数数量,包括位置参数和有默认值的参数。
例如,对于函数 def func(a, b=1),此属性会返回 2,因为 a 和 ``b``(尽管有默认值)都算作位置参数。
备注
它不包括仅限关键字参数。
co_posonlyargcount#
函数中仅限位置参数的数量。仅限位置参数是指不能通过关键字进行传递的参数。这个属性在 Python 3.8+ 中才被引入。
def func(a, b, /, c, d),其中 / 表示 a 和 b 只能作为位置参数传递。此时 co_posonlyargcount 为 2。
co_kwonlyargcount#
函数中仅限关键字参数的数量。仅限关键字参数指的是必须通过关键字传递的参数。
def func(a, b, *, c, d),其中 c 和 d 是仅限关键字参数。在此例中,co_kwonlyargcount 为 2。
co_nlocals#
函数中使用的局部变量的数量(包括形参)。局部变量不仅包括函数内部定义的变量,还包括形参。
1def func(a, b):
2 x = a + b
3 ...
对于上面的函数, co_nlocals 会是 *3*(a、b 和 x)。
co_varnames#
一个元组,包含了函数内所有局部变量的名称。它是按顺序列出的,形参排在前面,局部变量排在后面。
1def func(a, b):
2 x = a + b
3 ...
对于上面的函数, co_varnames 会是 ('a', 'b', 'x')
co_cellvars#
包含函数内被嵌套作用域引用的局部变量的名称。这些变量通常出现在闭包(closure)中,指向外部函数的局部变量。
备注
如果一个函数内有嵌套函数并且引用了外部函数的局部变量,那么这些外部变量会出现在 co_cellvars 中
co_freevars#
包含自由变量(自由变量是指在当前作用域外部定义的、但被当前作用域引用的变量)的名称。
与 co_cellvars 相对应,co_freevars 是指嵌套函数引用了外部作用域的变量。
1def outer():
2 a = 10
3 def inner():
4 print(a) # a 是自由变量
在 inner 函数的 codeobject.co_freevars 中,a 会被列出。
co_code#
一个字符串,表示函数中的字节码指令序列。字节码是 Python 编译器将源代码转化为机器可执行代码的中间表示。
co_consts#
包含函数字节码中使用的字面量常量的元组。字面量常量指的是代码中直接引用的常量,比如字符串、数字等。
对于 def func(): return 10 + 20,co_consts 可能包含 (10, 20)。
co_names#
包含函数字节码中使用的所有名称的元组。这个列表中的名称是函数所引用的任何标识符,比如变量名、函数名等。
对于 def func(a): return a + 1,co_names 会包含 ('a',)。
co_filename#
表示被编译的代码所在的文件的名称(绝对路径)。如果是在交互式环境中运行,通常返回 <stdin>。
如果代码在 example.py 中定义,co_filename 会返回 'd:\yourpath\example.py'。
co_firstlineno#
表示函数定义所在文件中的行号。
如果函数在文件的第 10 行开始,co_firstlineno 就是 10。
co_lnotab#
一个字符串,它映射了字节码偏移量与源代码行号之间的关系。此属性通常用于调试器或性能分析工具,帮助找到代码中的具体位置。
警告
自 Python 3.12 起,co_lnotab 已经被弃用,可能在未来的版本中删除。
co_stacksize#
表示执行代码时需要的最大栈大小。它是字节码执行过程中所需的栈的大小,以确保所有操作都可以在栈上完成。
co_flags#
一个整数,它对字节码解释器的各种标志进行了编码。通过它可以知道函数的一些特性,如是否是生成器函数、是否使用了闭包等。
例如,co_flags 为 0x20 可能意味着这个函数是一个生成器(即使用了 yield)。