【问题标题】:How can I get exception information after a call to PyRun_String(...) returns NULL?调用 PyRun_String(...) 返回 NULL 后如何获取异常信息?
【发布时间】:2014-08-06 18:28:37
【问题描述】:

我正在尝试运行以下代码:

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,表明引发了异常。如何访问此异常?

【问题讨论】:

    标签: python c python-c-api


    【解决方案1】:

    你可以这样做:

    PyErr_Print();
    

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

    And here is a question/answer 关于访问回溯对象。其中一个答案显示了如何将回溯复制到 C 字符串中,然后您可以将其写入文件(或您的情况下的 GUI)。

    【讨论】:

    • 我遇到的一个问题实际上是我似乎无法将 python 的 stdin/stdout/stderr 连接到控制台窗口(这是一个 GUI 应用程序,我不得不手动打开一个控制台窗口)。所以PyErr_Print() 根本帮不了我。
    • 您可以获得实际的回溯对象(我已经更新了我的答案以显示如何)。然后查看回溯对象中的字段以找出发生了什么。不过,我对回溯对象不是很熟悉。
    • 我只是尝试这样做,但似乎PyException_GetTraceback 未在 Python.h 中定义。
    • @Matt 哦,您一定使用的是 Python 2。由于您的问题中没有说明,我假设您使用的是最新的(Python 3)。在这种情况下,我认为您需要使用PyErr_Fetch()
    • 这是一个非常糟糕的假设,因为 Python 2 仍然被广泛使用,但是谢谢!
    【解决方案2】:

    由于您没有指定语句的数量SOME_PYTHON_CODE,因此可能存在另一个问题:根据 Boost Python 教程的this pagePyRun_String 的输出也取决于start 参数:

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

    接着说:

    使用 Py_eval_input 时,输入字符串必须包含单个表达式并返回其结果。使用 Py_file_input 时,字符串可以包含任意数量的语句,并且返回 None。 Py_single_input 的工作方式与 Py_file_input 相同,但只接受单个语句。

    因此,如果您在呼叫PyRun_String 时使用Py_file_input,您将始终收到None。相反,您可以使用Py_single_input

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-18
      • 2016-04-21
      • 2014-12-22
      相关资源
      最近更新 更多