【问题标题】:How do I properly use Python's C API and exceptions?如何正确使用 Python 的 C API 和异常?
【发布时间】:2013-12-12 12:48:49
【问题描述】:

如果我做类似的事情

 >>> 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!
    

    这个真的很奇怪。

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

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

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

【问题讨论】:

  • IIRC,只需 PyErr_SetString(PyExc_TypeError, "Oh no!") 就足够了 - 确保也跳过 C 方法中的所有其他代码。

标签: python c api python-c-api


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    作为Ignacio Vazquez-Abrams said:

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

    对于常见的异常类型,有一些方便的函数可以很容易地做到这一点。例如,PyErr_NoMemory 可以这样使用:

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

    【讨论】:

      猜你喜欢
      • 2012-05-07
      • 1970-01-01
      • 1970-01-01
      • 2014-08-08
      • 1970-01-01
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多