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

时间:2013-11-27 02:46:41

标签: python c api python-c-api

如果我做的话

 >>> 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中实现它?我找到了一些documentation,但我不确定我是否知道如何正确使用它。

以下是我一直在尝试的内容:

  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!
    

    这个真的很奇怪。

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

    编辑:我尝试了@ user2864740在评论中提出的建议并且效果很好!

     if(something) {
         PyErr_SetString(PyExc_TypeError, "Oh no!");
         return (PyObject *) NULL;
     }
    

2 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:0)

Ignacio Vazquez-Abrams said

  

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

有一些方便的功能,使这些操作对于常见的异常类型很容易实现。例如,PyErr_NoMemory可以这样使用:

PyObject *my_function(void)
{
    return PyErr_NoMemory();  // Sets the exception and returns NULL
}