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),其中 / 表示 ab 只能作为位置参数传递。此时 co_posonlyargcount2

co_kwonlyargcount#

函数中仅限关键字参数的数量。仅限关键字参数指的是必须通过关键字传递的参数。

def func(a, b, *, c, d),其中 cd 是仅限关键字参数。在此例中,co_kwonlyargcount2

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 + 20co_consts 可能包含 (10, 20)

co_names#

包含函数字节码中使用的所有名称的元组。这个列表中的名称是函数所引用的任何标识符,比如变量名、函数名等。

对于 def func(a): return a + 1co_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_flags0x20 可能意味着这个函数是一个生成器(即使用了 yield)。