关于python:如何在调用PyRun_String(…)后返回NULL时获取异常信息?

How can I get exception information after a call to PyRun_String(…) returns NULL?

我试图运行以下代码:

1
2
3
4
Py_Initialize();
PyObject *py_main = PyImport_AddModule("__main__");
PyObject *py_dict = PyModule_GetDict(py_main);
PyObject *ret = PyRun_String(SOME_PYTHON_CODE, Py_file_input, py_dict, py_dict);

但是在我生成的python代码(SOME_PYTHON_CODE)中似乎有一个错误,所以ret出现为NULL,表示引发了异常。 我怎样才能访问此例外?


你可以做:

1
PyErr_Print();

在标准错误上打印出标准堆栈跟踪。还有其他更精细的函数调用来处理错误,但我相信这是最简单,最简单的方法。

您还可以使用以下命令获取实际的异常/跟踪对象:

1
2
3
4
5
PyObject* ex = PyErr_Occurred();
if (ex) {
    PyObject* tb = PyException_GetTraceback(ex);
    /* Do something with tb */
}

如果设置了错误指示,则ex将为非NULL。有关详细信息,请参阅异常处理。

这里有一个关于访问回溯对象的问题/答案。其中一个答案显示了如何将回溯复制到C字符串中,然后可以将其写入文件(或者在您的情况下为GUI)。


由于您未指定语句数SOME_PYTHON_CODE,因此可能存在另一个问题:根据Boost Python教程的此页面,PyRun_String的输出还取决于start参数:

  • Py_eval_input用于解释孤立的表达式
  • Py_file_input用于解释语句序列
  • Py_single_input用于解释单个语句

它继续说:

When using Py_eval_input, the input string must contain a single expression and its result is returned. When using Py_file_input, the string can contain an abitrary number of statements and None is returned. Py_single_input works in the same way as Py_file_input but only accepts a single statement.

因此,如果您在PyRun_String的调用中使用Py_file_input,则始终会收到None。相反,您可以使用Py_single_input