问题 Boost.Python自定义异常类


我正在使用Boost.Python实现Python扩展模块。该模块应该定义自己继承的自定义异常类 Exception。我怎么做?


9845
2018-03-08 15:34


起源

让你的错误继承自己 Exception; StandardError 由python标准库中的工具生成的错误使用。 - Daenyth
@Daenyth:你是对的。我已经修改了这个问题。 - user763305


答案:


以下函数创建一个新的Python异常类,并将其添加到当前范围。如果在模块初始化函数中调用它,则将其添加到模块中。

第一个参数是新异常类的名称。第二个参数是新异常类的基类的类型对象;它默认为类型对象 Exception。返回值是新异常类的类型对象。

PyObject* createExceptionClass(const char* name, PyObject* baseTypeObj = PyExc_Exception)
{
    using std::string;
    namespace bp = boost::python;

    string scopeName = bp::extract<string>(bp::scope().attr("__name__"));
    string qualifiedName0 = scopeName + "." + name;
    char* qualifiedName1 = const_cast<char*>(qualifiedName0.c_str());

    PyObject* typeObj = PyErr_NewException(qualifiedName1, baseTypeObj, 0);
    if(!typeObj) bp::throw_error_already_set();
    bp::scope().attr(name) = bp::handle<>(bp::borrowed(typeObj));
    return typeObj;
}

使用如下功能:

在模块初始化函数中调用函数并将返回值存储在全局变量中:

PyObject* myExceptionTypeObj = 0;

BOOST_PYTHON_MODULE(MyModule)
{
    ...
    myExceptionTypeObj = createExceptionClass("MyException");
    ...
}

提高类型的异常 MyModule.MyException

PyErr_SetString(myExceptionTypeObj, "Oh my!")

13
2018-03-13 19:08



说 MyException 真的映射到C ++类型。我将如何揭露其成员? - Barry


@Kenny:

如果你参考

PyErr_SetString(myExceptionTypeObj, "Oh my!")

我不认为这是“将字符串复制到全局对象”。相反,它设置Python的内部错误指示符,以便解释器在下一个错误指示符检查时引发myExceptionTypeObj的实例。

Python的异常处理与(每个Python线程)全局错误指示器一起使用,这是通过C API提出异常的常用方法。

我对此的看法是,如果您此时持有GIL并且在您输入C代码的Python线程中正确导致异常,那么您就是安全的。


-1
2018-04-24 09:15