如何正确使用Python的C API和异常?

问题描述 投票:0回答:2

如果我做类似的事情

 >>> x = int(1,2,3,4,5)

我立即收到一个致命错误(如果是在预先编写的脚本中,则会结束程序执行)

 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 TypeError: int() takes at most 2 arguments (5 given)

x
保持未定义:

 >>> x
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 NameError: name 'x' is not defined

我将如何在 Python 的 C API 中实现它?我找到了一些文档,但我不确定我是否知道如何正确使用它。

这是我一直在尝试的:

  1. 打印:

    if(something) {
        PyErr_SetString(PyExc_TypeError, "Oh no!");
        PyErr_Print();
    }
    

    不幸的是,这仅打印异常并且程序继续。另外,如果我理解正确的话,

    PyErr_Print()
    会从某种队列中删除异常,以便Python认为它已被处理。这就是它的样子:

    >>> import awesomemod
    >>> x = awesomemod.thing()
    TypeError: Oh no!
    >>> x # x is defined because the function returns None eventually
    >>> 
    
  2. PyErr_Occurred()
    :

    if(something) {
        PyErr_SetString(PyExc_TypeError, "Oh no!");
        PyErr_Occurred();
    }
    

    行为:

    >>> import awesomemod
    >>> awesomemod.thing()
    >>>
    TypeError: Oh no!
    >>>
    

    所以它有点晚了...

  3. return PyErr_Occurred()
    :

    if(something) {
        PyErr_SetString(PyExc_TypeError, "Oh no!");
        return PyErr_Occurred();
    }
    

    行为:

    >>> import awesomemod
    >>> awesomemod.thing()
    <type 'exceptions.TypeError'>
    >>>
    TypeError: Oh no!
    

    这个真的很奇怪。

我需要做什么才能获得内置函数的行为?

编辑:我尝试了@user2864740在评论中建议的内容,效果非常好!

 if(something) {
     PyErr_SetString(PyExc_TypeError, "Oh no!");
     return (PyObject *) NULL;
 }
python c api python-c-api
2个回答
18
投票

在 C 中引发异常是通过设置异常对象或字符串然后从函数返回

NULL
来完成的。


5
投票

正如 Ignacio Vazquez-Abrams 所说

在 C 中引发异常是通过设置异常对象或字符串然后从函数返回 NULL 来完成的。

有一些方便的函数可以让常见的异常类型变得容易。例如,

PyErr_NoMemory
可以这样使用:

PyObject *my_function(void)
{
    return PyErr_NoMemory();  // Sets the exception and returns NULL
}
© www.soinside.com 2019 - 2024. All rights reserved.