【问题标题】:Boost.Python custom exception classBoost.Python 自定义异常类
【发布时间】:2012-03-26 02:09:35
【问题描述】:

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

【问题讨论】:

  • 让你的错误继承自ExceptionStandardError 被 python 标准库中的工具生成的错误使用。
  • @Daenyth:你是对的。我已经修改了问题。

标签: c++ python exception boost-python


【解决方案1】:

@肯尼:

如果你参考

PyErr_SetString(myExceptionTypeObj, "Oh my!")

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

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

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

【讨论】:

  • 肯尼是谁?我在这个讨论中没有看到任何肯尼...
【解决方案2】:

以下函数创建一个新的 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!")

【讨论】:

  • MyException 真的映射到 C++ 类型。我将如何暴露其成员?
猜你喜欢
  • 2010-10-02
  • 2021-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-12
  • 1970-01-01
  • 2019-07-15
  • 1970-01-01
相关资源
最近更新 更多