boost::python 导出自定义异常并继承自 Python 的异常

gle*_*nnr 3 c++ exception boost-python

boost::python 导出自定义异常的公认答案显示了如何从 C++ 导出自定义异常类,而Boost.Python 自定义异常类显示了如何导出从 Python 的异常继承的异常类。我怎样才能做到这两点?即公开一个异常类,该类具有用于检索信息的自定义方法,并且该类也可以从 Python 的异常派生。

gle*_*nnr 5

Jim Bosch 在C++-sig list上建议的一个可行的解决方案是使用组合而不是从包装的 C++ 异常继承。代码必须像这里所做的那样创建一个 Python 异常,然后添加包装的 C++ 异常作为 Python 异常的实例变量。

void translator(const MyCPPException &x) {
    bp::object exc(x); // wrap the C++ exception

    bp::object exc_t(bp::handle<>(bp::borrowed(exceptionType)));
    exc_t.attr("cause") = exc; // add the wrapped exception to the Python exception

    PyErr_SetString(exceptionType, x.what());
}
Run Code Online (Sandbox Code Playgroud)

然后可以像这样从 Python 访问包装的 C++ 异常:

try:
    ...
except MyModule.MyCPPExceptionType as e:
    cause = e.cause # wrapped exception can be accessed here
Run Code Online (Sandbox Code Playgroud)

但异常也会被捕获

try:
    ...
except Exception:
    ...
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`exc_t.attr("cause") = exc;` 将 C++ 异常实例作为属性添加到 Python 异常 *class*。因此,如果您在 Python 中捕获异常实例 e1 并保留对它的引用,则此类 C++ 异常的第二次引发将更改 e1 的原因属性以引用新的 C++ 异常实例。 (2认同)