如何正确使用 Python 的 C API 和异常? [英] How do I properly use Python's C API and exceptions?

查看:18
本文介绍了如何正确使用 Python 的 C API 和异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我做类似的事情

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

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

 回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中类型错误:int() 最多接受 2 个参数(给定 5 个)

x 保持未定义:

 >>>X回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中NameError: 名称 'x' 未定义

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

这是我一直在尝试的:

  1. 打印:

    if(something) {PyErr_SetString(PyExc_TypeError, "哦不!");PyErr_Print();}

    不幸的是,这只会打印异常并且程序继续.此外,如果我理解正确的话,PyErr_Print() 会从某种队列中删除异常,因此 Python 认为它已被处理.这是它的样子:

    <预><代码>>>>导入真棒模组>>>x = awesomemod.thing()类型错误:哦不!>>>x # x 被定义是因为函数最终返回 None>>>

  2. PyErr_Occurred():

    if(something) {PyErr_SetString(PyExc_TypeError, "哦不!");PyErr_Occurred();}

    行为:

    <预><代码>>>>导入真棒模组>>>真棒mod.thing()>>>类型错误:哦不!>>>

    所以它做的有点晚......

  3. 返回 PyErr_Occurred():

    if(something) {PyErr_SetString(PyExc_TypeError, "哦不!");返回 PyErr_Occurred();}

    行为:

    <预><代码>>>>导入真棒模组>>>真棒mod.thing()<type 'exceptions.TypeError'>>>>类型错误:哦不!

    这个真的很奇怪.

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

我尝试了@user2864740 在评论中建议的内容,效果很好!

 if(something) {PyErr_SetString(PyExc_TypeError, "哦不!");返回(PyObject *)NULL;}

解决方案

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

if I do something like

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

I immediately get a fatal error (one that would end program execution if it was in a pre-written script)

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

and x remains undefined:

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

How would I go about implementing that in Python's C API? I found some documentation for it, but I am not sure that I know how to use it correctly.

Here is what I have been trying:

  1. Print:

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

    This, unfortunately, only prints the exception and the program continues. Additionally,—if I understand it correctly—PyErr_Print() removes the exception from some sort of queue so Python thinks that it is handled. This is what it looks like:

    >>> 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();
    }
    

    Behavior:

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

    So it does it kind of late...

  3. return PyErr_Occurred():

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

    Behavior:

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

    This one is just really weird.

What do I need to do to get the behavior of built-in functions?

Edit: I tried what @user2864740 suggested in a comment and it worked perfectly!

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

解决方案

Raising an exception in C is done by setting the exception object or string and then returning NULL from the function.

这篇关于如何正确使用 Python 的 C API 和异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆