附录B: Pybind11 API速查
快速参考卡片格式,方便日常开发查阅。
B.1 核心宏
Section titled “B.1 核心宏”| 宏 | 说明 | 示例 |
|---|---|---|
PYBIND11_MODULE(name, m) | 定义模块入口,m 为模块对象 | PYBIND11_MODULE(example, m) { ... } |
PYBIND11_OVERLOAD_INT(ret_type, cfunc, name, ...) | 虚函数重载 | 用于 def_property_virtual |
PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type) | 声明持有者类型 | PYBIND11_DECLARE_HOLDER_TYPE(Foo, std::shared_ptr<Foo>) |
PYBIND11_PLUGIN(name, m) | 旧版模块定义(已废弃) | 不建议使用 |
模块定义示例
Section titled “模块定义示例”// 基本模块PYBIND11_MODULE(my_module, m) { m.doc() = "My module documentation";
// 绑定函数 m.def("func", &func, "Documentation string");
// 绑定类 py::class_<MyClass>(m, "MyClass") .def(py::init<>()) .def("method", &MyClass::method);}B.2 类型转换函数
Section titled “B.2 类型转换函数”| 类型 | 说明 |
|---|---|
py::handle | 非拥有型引用,引用计数不变 |
py::object | 拥有型引用,构造时增加引用计数 |
py::cast<T>(obj) | 将 Python 对象转为 C++ 类型 |
py::implicitly_convertible<A, B>() | 声明隐式转换 |
cast 转换
Section titled “cast 转换”// 显式转换int val = py::cast<int>(python_object);std::string str = py::cast<std::string>(py_str);
// 安全转换(失败时抛异常)py::object obj = py::cast<py::object>(input);
// 返回 Python 对象py::object make_py_int(int x) { return py::cast(x); // 自动创建 Python int}handle vs object
Section titled “handle vs object”void foo(py::handle obj) { // handle:不改变引用计数,用于函数参数 // 不保存handle,调用者负责管理生命周期}
void bar(py::object obj) { // object:保存副本,增加引用计数 // 安全地保存对象 this->saved_obj = obj; // 增加引用}B.3 类定义函数
Section titled “B.3 类定义函数”py::class_<MyClass>(m, "MyClass") .def(py::init<>()) // 构造函数 .def(py::init<double, int>()) // 重载构造函数 .def("method", &MyClass::method) // 成员函数 .def_static("static_method", &MyClass::static_method) // 静态方法 .def_property("prop", &MyClass::get, &MyClass::set) // 属性 .def_readwrite("field", &MyClass::field) // 公开成员变量 .def_readonly("const_field", &MyClass::const_field) // 只读成员 .doc() = "Class documentation"; // 类文档py::class_<MyClass>(m, "MyClass") // 读写属性 .def_property("name", &GetName, &SetName)
// 只读属性 .def_property_readonly("id", &MyClass::get_id)
// 带 docstring 的属性 .def_property("value", [](const MyClass& self) { return self.value; }, [](MyClass& self, int v) { self.value = v; }, "The value property")
// C++11 lambda 替代成员函数 .def("__repr__", [](const MyClass& self) { return "<MyClass>"; });运算符和特殊方法
Section titled “运算符和特殊方法”py::class_<Vector2>(m, "Vector2") .def(py::init<double, double>()) .def(self + self) // __add__ .def(self - self) // __sub__ .def(self * double()) // __mul__ .def(-self) // __neg__ .def("__eq__", [](const Vector2& a, const Vector2& b) { return a.x == b.x && a.y == b.y; }) .def("__str__", [](const Vector2& v) { return py::str("Vector2({}, {})").format(v.x, v.y); });B.4 异常处理
Section titled “B.4 异常处理”// 注册自定义异常py::register_exception<MyException>(m, "MyException");
// 注册异常(有父类)py::register_exception<MyException>(m, "MyException", PyExc_RuntimeError);
// 在 C++ 中抛出 Python 异常void throw_py_error() { PyErr_SetString(PyExc_ValueError, "Invalid value"); throw py::error_already_set();}try { // 调用可能抛出异常的代码 py::object result = py::cast(x).attr("method")();} catch (const py::error_already_set& e) { // 处理 Python 异常 std::cerr << "Python error: " << e.what() << std::endl; // 清理异常状态 e.restore(); throw; // 重新抛出给 Python}
// 更简洁的写法try { // ...} catch (const py::error_already_set& e) { PyErr_WriteUnraisable(e.ptr());}| 类 | 说明 |
|---|---|
py::error_already_set | Python 异常正在设置中 |
py::stop_iteration | 迭代器停止 |
py::cast_error | 类型转换失败 |
B.5 常用工具函数
Section titled “B.5 常用工具函数”// 简单函数绑定m.def("func", &func, "doc string");
// 带默认参数m.def("func", &func, py::arg("x") = 10);
// 多参数m.def("func", [](int a, int b, int c) { return a + b + c; }, py::arg("a"), py::arg("b"), py::arg("c") = 0);// 制造 Python 迭代器py::make_iterator(iterable.begin(), iterable.end())
// 返回迭代器(需要 KeepAlive)m.def("range", [](int n) { return py::make_iterator(std::range(0, n));}, py::keep_alive<0, 1>());
// 范围迭代for (auto item : py::make_iterator(obj, obj.end())) { // 处理 item}智能指针持有
Section titled “智能指针持有”// std::shared_ptrpy::class_<MyClass, std::shared_ptr<MyClass>>(m, "MyClass") .def(py::init<>());
// std::unique_ptr(需要_return_value_policy)py::class_<MyClass, std::unique_ptr<MyClass, py::nodelete>>(m, "MyClass");
// 自定义 holder 类型PYBIND11_DECLARE_HOLDER_TYPE(T, Holder<T>);m.def("func", [](int a, int b, bool c) { }, py::arg("a"), py::arg("b"), py::arg("c") = false);
// 使用 kwargsm.def("func", [](py::kwargs& kwargs) { if (kwargs.contains("verbose")) { bool verbose = kwargs["verbose"].cast<bool>(); }}, "Function with kwargs");// 隐式类型转换py::class_<A>(m, "A");py::class_<B>(m, "B").def(py::init<A>());
py::implicitly_convertible<A, B>();
// 从 C++ 类型列表创建 tuple/listpy::list make_list(const std::vector<int>& v) { py::list result; for (auto x : v) result.append(x); return result;}
py::tuple make_tuple(const std::pair<int, int>& p) { return py::make_tuple(p.first, p.second);}