所以我有一个 C 程序,它使用嵌入式 CPython 解释器来执行 Python 代码。问题是,如果Python代码有错误,解释器提供的行号信息有点无用,因为每次调用PyEval_EvalCodeEx
从 1 开始计算行数。因此,每当我执行代码时,我都会以行号的形式为 Python 解释器提供一个上下文。
有办法做到这一点吗?查看 PyEval_EvalCodeEx
的定义,这最终是 Python C-API 公开的代码执行的最低级别函数,我看不到任何传递行号信息的机会。
文档简单地写着:
PyObject* PyEval_EvalCodeEx(PyObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, PyObject **defs, int defcount, PyObject *closure)
block 引用>Evaluate a precompiled code object, given a particular environment for its evaluation. This environment consists of dictionaries of global and local variables, arrays of arguments, keywords and defaults, and a closure tuple of cells.
那么这是不可能做到的吗?
最佳答案
如果您查看 PyEval_EvalCodeEx()
的实现,您可能会发现第一个参数被转换为 PyCodeObject *
,位于函数体的开头:
/* File: ceval.c */
PyObject *
PyEval_EvalCodeEx(PyObject *_co, ...)
{
PyCodeObject* co = (PyCodeObject*)_co;
...
}
如果您查看 PyCodeObject
,就会发现有一个名为 co_firSTLineno
的成员:
/* File: code.h */
typedef struct {
PyObject_HEAD
...
PyObject *co_filename; /* unicode (where it was loaded from) */
PyObject *co_name; /* unicode (name, for reference) */
int co_firstlineno; /* first source line number */
PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) See
Objects/lnotab_notes.txt for details. */
...
} PyCodeObject;
所以我想在调用 PyEval_EvalCodeEx()
函数之前修改 co_firstfileno
字段可能就足够了,如下所示:
((PyCodeObject *)co)->co_firstlineno = 42;
PyEval_EvalCodeEx(co, ...);
这应该足够了,据我记得,您甚至不需要修改 co_lnotab
,因为它包含与 co_firSTLineno
的偏移量,而不是绝对位置.
关于python - 将行号传递给嵌入式 Python 解释器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24827224/