代码对象¶
代码对象是 CPython 实现的底层细节。每一个都代表一块尚未绑定到函数中的可执行代码。
-
type PyCodeObject¶
用于描述代码对象的 C 结构。此类型的字段随时可能更改。
-
PyTypeObject PyCode_Type¶
这是
PyTypeObject
的一个实例,代表 Python 代码对象。
-
Py_ssize_t PyCode_GetNumFree(PyCodeObject *co)¶
返回代码对象中 自由(闭包)变量 的数量。
-
int PyUnstable_Code_GetFirstFree(PyCodeObject *co)¶
- 这是 不稳定 API。它可能在小版本更新中更改,恕不另行通知。
返回代码对象中第一个 自由(闭包)变量 的位置。
在 3.13 版本中更改:从
PyCode_GetFirstFree
重命名,作为 不稳定 C API 的一部分。旧名称已弃用,但会保留到签名再次更改为止。
-
PyCodeObject *PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)¶
- 这是 不稳定 API。它可能在小版本更新中更改,恕不另行通知。
返回一个新的代码对象。如果您需要一个虚拟代码对象来创建帧,请使用
PyCode_NewEmpty()
代替。由于字节码的定义经常更改,直接调用
PyUnstable_Code_New()
可能会将您绑定到特定的 Python 版本。此函数的许多参数以复杂的方式相互依赖,这意味着值的细微更改很可能导致执行不正确或 VM 崩溃。仅在极其谨慎的情况下使用此功能。
在 3.11 版本中更改:添加了
qualname
和exceptiontable
参数。在 3.12 版本中更改:从
PyCode_New
重命名,作为 不稳定 C API 的一部分。旧名称已弃用,但会保留到签名再次更改为止。
-
PyCodeObject *PyUnstable_Code_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)¶
- 这是 不稳定 API。它可能在小版本更新中更改,恕不另行通知。
类似于
PyUnstable_Code_New()
,但为仅限位置参数添加了额外的“posonlyargcount”。适用于PyUnstable_Code_New
的注意事项也适用于此函数。在 3.8 版本中添加:作为
PyCode_NewWithPosOnlyArgs
在 3.11 版本中更改:添加了
qualname
和exceptiontable
参数。3.12 版本更改: 重命名为
PyUnstable_Code_NewWithPosOnlyArgs
。旧名称已弃用,但会保留可用,直到签名再次更改。
-
PyCodeObject *PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)¶
- 返回值:新引用。
返回一个新的空代码对象,其中包含指定的文件名、函数名称和首行行号。如果执行生成的代码对象,则会引发
Exception
异常。
-
int PyCode_Addr2Line(PyCodeObject *co, int byte_offset)¶
返回发生在
byte_offset
或之前并在其之后结束的指令的行号。 如果您只需要帧的行号,请改用PyFrame_GetLineNumber()
。为了高效地迭代代码对象中的行号,请使用 PEP 626 中描述的 API。
-
int PyCode_Addr2Location(PyObject *co, int byte_offset, int *start_line, int *start_column, int *end_line, int *end_column)¶
将传递的
int
指针设置为byte_offset
处指令的源代码行和列号。当任何特定元素的信息不可用时,将值设置为0
。如果函数成功,则返回
1
,否则返回 0。在 3.11 版本中新增。
-
PyObject *PyCode_GetCode(PyCodeObject *co)¶
等效于 Python 代码
getattr(co, 'co_code')
。 返回对PyBytesObject
的强引用,该引用表示代码对象中的字节码。 如果出错,则返回NULL
并引发异常。此
PyBytesObject
可能会由解释器按需创建,并且不一定表示 CPython 实际执行的字节码。此函数的主要用例是调试器和性能分析器。在 3.11 版本中新增。
-
PyObject *PyCode_GetVarnames(PyCodeObject *co)¶
等效于 Python 代码
getattr(co, 'co_varnames')
。 返回对包含局部变量名称的PyTupleObject
的新引用。 如果出错,则返回NULL
并引发异常。在 3.11 版本中新增。
-
PyObject *PyCode_GetCellvars(PyCodeObject *co)¶
等效于 Python 代码
getattr(co, 'co_cellvars')
。 返回对包含嵌套函数引用的局部变量名称的PyTupleObject
的新引用。 如果出错,则返回NULL
并引发异常。在 3.11 版本中新增。
-
PyObject *PyCode_GetFreevars(PyCodeObject *co)¶
等效于 Python 代码
getattr(co, 'co_freevars')
。 返回对包含自由(闭包)变量名称的PyTupleObject
的新引用。 如果出错,则返回NULL
并引发异常。在 3.11 版本中新增。
-
int PyCode_AddWatcher(PyCode_WatchCallback callback)¶
将 *callback* 注册为当前解释器的代码对象监视器。 返回一个 ID,该 ID 可以传递给
PyCode_ClearWatcher()
。如果发生错误(例如,没有更多可用的监视器 ID),则返回-1
并设置异常。在 3.12 版本中新增。
-
int PyCode_ClearWatcher(int watcher_id)¶
清除由 *watcher_id* 标识的监视器,该监视器先前由当前解释器的
PyCode_AddWatcher()
返回。 成功时返回0
,或者在出错时返回-1
并设置异常(例如,如果给定的 *watcher_id* 从未注册)。在 3.12 版本中新增。
-
type PyCodeEvent¶
可能的代码对象监视器事件的枚举: -
PY_CODE_EVENT_CREATE
-PY_CODE_EVENT_DESTROY
在 3.12 版本中新增。
-
typedef int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject *co)¶
代码对象监视器回调函数的类型。
如果 *event* 是
PY_CODE_EVENT_CREATE
,则在 co 完全初始化后调用回调。 否则,在销毁 *co* 发生之前调用回调,因此可以检查 *co* 的先前状态。如果 *event* 是
PY_CODE_EVENT_DESTROY
,则在回调中引用即将被销毁的代码对象将会使其复活,并阻止其此时被释放。 当复活的对象稍后被销毁时,届时处于活动状态的任何监视器回调将再次被调用。此 API 的用户不应依赖于内部运行时实现的细节。这些细节可能包括但不限于代码对象创建和销毁的确切顺序和时间。尽管这些细节的更改可能会导致观察者可观察到的差异(包括是否调用回调),但这不会改变正在执行的 Python 代码的语义。
如果回调设置了异常,则必须返回
-1
;此异常将使用PyErr_WriteUnraisable()
打印为不可引发的异常。否则,它应返回0
。在进入回调时,可能已经存在一个待处理的异常设置。在这种情况下,回调应返回
0
,并且仍然设置相同的异常。这意味着回调可能不会调用任何其他可以设置异常的 API,除非它先保存并清除异常状态,然后在返回之前恢复它。在 3.12 版本中新增。
额外信息¶
为了支持对帧求值的底层扩展,例如外部即时编译器,可以将任意额外数据附加到代码对象。
这些函数是不稳定的 C API 层的一部分:此功能是 CPython 实现细节,API 可能会在没有弃用警告的情况下发生更改。
-
Py_ssize_t PyUnstable_Eval_RequestCodeExtraIndex(freefunc free)¶
- 这是 不稳定 API。它可能在小版本更新中更改,恕不另行通知。
返回一个用于向代码对象添加数据的新不透明索引值。
您通常(每个解释器)调用此函数一次,并使用结果与
PyCode_GetExtra
和PyCode_SetExtra
一起操作单个代码对象上的数据。如果 free 不为
NULL
:当代码对象被释放时,将在新索引下存储的非NULL
数据上调用 free。在存储PyObject
时,请使用Py_DecRef()
。3.6 版本新增: 作为
_PyEval_RequestCodeExtraIndex
在 3.12 版本中更改: 重命名为
PyUnstable_Eval_RequestCodeExtraIndex
。旧的私有名称已弃用,但在 API 更改之前仍然可用。
-
int PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra)¶
- 这是 不稳定 API。它可能在小版本更新中更改,恕不另行通知。
将 extra 设置为给定索引下存储的额外数据。成功时返回 0。失败时设置异常并返回 -1。
如果在该索引下未设置任何数据,则将 extra 设置为
NULL
并返回 0,而不设置异常。3.6 版本新增: 作为
_PyCode_GetExtra
在 3.12 版本中更改: 重命名为
PyUnstable_Code_GetExtra
。旧的私有名称已弃用,但在 API 更改之前仍然可用。
-
int PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra)¶
- 这是 不稳定 API。它可能在小版本更新中更改,恕不另行通知。
将给定索引下存储的额外数据设置为 extra。成功时返回 0。失败时设置异常并返回 -1。
3.6 版本新增: 作为
_PyCode_SetExtra
在 3.12 版本中更改: 重命名为
PyUnstable_Code_SetExtra
。旧的私有名称已弃用,但在 API 更改之前仍然可用。