2012-03-08 112 views
11

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

+1

使你的错误继承自'Exception';标准错误由Python标准库中的工具生成的错误使用。 – Daenyth 2012-03-08 16:16:13

+0

@Daenyth:你说得对。我修改了这个问题。 – user763305 2012-03-10 11:35:23

回答

12

以下函数创建一个新的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; 
} 

使用功能如下:

呼叫在模块初始化函数的功能和存储在一个全局变量返回值:MyModule.MyException类型的

PyObject* myExceptionTypeObj = 0; 

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

引发异常:

PyErr_SetString(myExceptionTypeObj, "Oh my!") 
+4

说'MyException'确实映射到一个C++类型。我将如何揭露其成员? – Barry 2016-06-14 16:48:56

-1

@Kenny:

如果您参考

PyErr_SetString(myExceptionTypeObj, "Oh my!") 

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

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

如果您在此刻持有GIL并且会在您的C代码输入的Python线程中正确地导致异常,那么您可以放心。