如何通过pybind11在python中捕获C++的异常?

Posted

技术标签:

【中文标题】如何通过pybind11在python中捕获C++的异常?【英文标题】:How to catch the exception from C++ in python via pybind11? 【发布时间】:2020-06-24 01:58:44 【问题描述】:

我正在使用 pybind11 在 python 中编写代码。

比如我有test1.cpp、test_pybind.cpp和example.py

heaan_pybind.cpp

namespace py=pybind11;
PYBIND11_MODULE(test, m)

  py::class_<test1>(m, "test1")
  .def("fn", ...)

在example.py中,我想控制如下异常。

import test
while True:
  try:
    test.test1.fn(...)
  except ???:
    print("exception error.")

如何从 example.py 中的 test.cpp 捕获错误或异常?

【问题讨论】:

【参考方案1】:

简单的方法是确保您想要在 python 中捕获的所有 c++ 异常也是绑定的一部分。

所以在你的模块中,假设你有一个名为 CppExp 的 cpp 异常类型,你会做类似的事情

namespace py=pybind11;
PYBIND11_MODULE(test, m)

  py::register_exception<CppExp>(module, "PyExp");

这将创建一个名为PyExp 的新python 异常,它会导致任何抛出CppExp 的代码将其重新映射到python 异常中。

然后在你的python代码中你可以做

import test
while True:
  try:
    test.test1.fn(...)
  except test.PyExp as ex:
    print("exception error.", ex)

关于异常处理的其他 pybind11 文档在这里: https://pybind11.readthedocs.io/en/master/advanced/exceptions.html

如果您的 c++ 异常具有要转换为 python 的自定义字段或方法,则必须按照我在此处的回答实际修改 pybind11 代码: How can you bind exceptions with custom fields and constructors in pybind11 and still have them function as python exception?

【讨论】:

【参考方案2】:

如果你不知道异常的类型,你可以简单地捕获最通用的类​​型,例如Exception。见下文

import test
while True:
  try:
    test.test1.fn(...)
  except Exception:
    print("exception error.")

【讨论】:

以上是关于如何通过pybind11在python中捕获C++的异常?的主要内容,如果未能解决你的问题,请参考以下文章