pybind11 参考文档全解从模块宏、类型体系到嵌入解释器的核心 API 速查【免费下载链接】pybind11Seamless operability between C11 and Python项目地址: https://gitcode.com/GitHub_Trending/py/pybind11本文以 pybind11 仓库中的 docs/reference.rst 为主体骨架系统梳理 pybind11 公开 API 的参考索引从PYBIND11_MODULE模块入口宏、任意/特定 Python 类型的便捷包装类handle、object、object_api、类型转换辅助函数、def/py::class_的注解参数到解释器嵌入、C 流重定向、内建函数、虚函数覆盖宏与异常类型逐一结合 include/pybind11 下的头文件源码展开讲解。读完本文你将能够快速定位 pybind11 各层 API 的声明位置与使用方式理解引用计数语义、宏展开机制与异常/覆盖机制的底层实现并据此写出正确的绑定代码。说明docs/reference.rst开头明确提示这份参考文档是不完整的incomplete——它主要充当“API 索引 命名空间锚点”的角色大量细节需要回到pybind11头文件本身去查阅。因此本文的定位是以 reference.rst 的章节骨架为地图带领读者深入对应头文件源码两相结合形成一份可检索、可引用的 API 速查指南。Macros一切绑定的人口PYBIND11_MODULEreference.rst 的第一个章节是PYBIND11_MODULE。这是 pybind11 扩展模块的入口宏定义于 include/pybind11/detail/common.h#define PYBIND11_MODULE(name, variable, ...) \ PYBIND11_MODULE_PYINIT(name, ##__VA_ARGS__) \ PYBIND11_MODULE_EXEC(name, variable)该宏展开为两部分PYBIND11_MODULE_PYINITcommon.h生成名为PyInit_name的模块初始化函数内部依次执行PYBIND11_CHECK_PYTHON_VERSION、pybind11::detail::ensure_internals()并构造一个静态PyModuleDef含多解释器支持所需的 slots最后PyModuleDef_Init返回模块对象。注释明确指出该函数在每个子解释器中导入模块时都会运行一次PyModuleDef可以静态但PyObject*不能跨解释器共享。PYBIND11_MODULE_EXECcommon.h生成模块的执行回调pybind11_exec_name把模块对象以pybind11::reinterpret_borrowmodule_包装后调用用户提供的初始化函数pybind11_init_name(m)。经典用法来自 common.h 的文档注释PYBIND11_MODULE(example, m) { m.doc() pybind11 example module; // Add bindings here m.def(foo, []() { return Hello, World!; }); }自 2.13.0 起第三个及以后的宏参数可选用于声明扩展模块对 GIL / 多解释器的特性支持common.hpy::mod_gil_not_used()模块可在无 GIL自由线程环境下安全运行py::multiple_interpreters::per_interpreter_gil()每个解释器独立 GILpy::multiple_interpreters::shared_gil()共享 GILpy::multiple_interpreters::not_supported()不支持多解释器。PYBIND11_MODULE(example, m, py::mod_gil_not_used()) { m.doc() pybind11 example module safe to run without the GIL; m.def(foo, []() { return Hello, Free-threaded World!; }); }仓库中对应的实际用例见 tests/pybind11_tests.cpp测试主模块即通过PYBIND11_MODULE(pybind11_tests, m)注册以及 include/pybind11/pybind11.h 中标记为废弃的PYBIND11_PLUGIN提示改用PYBIND11_MODULE或module_::create_extension_module。任意 Python 类型的便捷包装类reference.rst 将类型包装分为三层object_api公共成员函数、handle无引用计数、object带引用计数。object_api公共操作混入类object_api定义于 include/pybind11/pytypes.h是一个 CRTP 混入类为handle、object及各类 accessor 提供公共成员函数唯一要求是派生类实现PyObject *Derived::ptr() const。其核心成员包括pytypes.h迭代协议begin()/end()等价于 Python 的iter()下标访问operator[]支持handle键、右值object键和const char *字符串键转换时调用__getitem__赋值时调用__setitem__属性访问attr(handle)/attr(object)/attr(const char *)转换时调用getattr/setattr另有带类型注解的attr_with_type_hintT实现在 include/pybind11/cast.h用于写入__annotations__参数解包operator*返回args_proxy匹配 Python 的*解包元组/列表为位置参数、**解包字典为关键字参数成员测试contains(T)等价于item in obj函数调用operator()假定对象可调用函数或实现__call__返回object必要时用handle::cast()转回 C 类型。这些 accessor 的策略类obj_attr、str_attr、generic_item、sequence_item、list_item、tuple_item见 pytypes.h定义了属性/下标访问的具体行为。handle无引用计数的裸包装handle是 Python C APIPyObject *的薄封装pytypes.h不负责引用计数默认构造时指针为nullptr。关键接口ptr()取回底层PyObject *inc_ref()/dec_ref()手动增减引用计数Py_XINCREF/Py_XDECREF当定义PYBIND11_ASSERT_GIL_HELD_INCREF_DECREF时会在未持有 GIL 的情况下调用这些函数时抛出运行时错误见throw_gilstate_errorpytypes.hcastT()尝试把 Python 对象转换为 C 类型T失败抛出cast_erroroperator bool()判断是否包裹了有效对象。object带引用计数的 RAII 包装object继承自handle构造时可选增加引用计数析构时总是调用dec_ref()pytypes.h拷贝构造增加引用计数移动构造窃取引用并把源指针置空析构自动释放。注释明确指出“一致使用object时第一次尝试就能把引用计数写对”。需要特别注意的是两个引用所有权转换函数reference.rst 单独列出reinterpret_borrowT(handle)借用borrow引用即新对象不增加引用计数——调用方仍持有所有权要求p已是目标类型pytypes.hreinterpret_stealT(handle)窃取steal引用接管所有权pytypes.h。旧式object(handle, bool is_borrowed)构造已标记废弃统一改为这两个函数pytypes.h。特定 Python 类型的便捷类与类型转换辅助函数module_与pytypes组reference.rst 的“Convenience classes for specific Python types”章节引用module_类定义于 include/pybind11/pybind11.h以及doxygengroup:: pytypes组。pytypes组囊括了 include/pybind11/pytypes.h 中几乎所有内置类型包装str、bytes、bytearray、list、tuple、dict、set、frozenset、int_、float_、bool_、slice、type、capsule、ellipsis、none、iterator、function、memoryview等每个类型都提供与 Python 内建行为对应的成员方法如str::attr、dict::contains、list::append等。type_caster_pyobject_ptr.h和type_caster_base.h则负责这些类型在函数参数/返回值位置的自动转换。make_tuple与迭代器工厂reference.rst 列出以下“转换为 Python 类型的便捷函数”make_tuple(Args...)构建typing::Tuple元组include/pybind11/cast.h返回类型带有类型提示注解make_iterator(Iterator, Sentinel, Extra...)/make_iterator(Type, Extra...)把 C 迭代器范围或容器转换为 Python 迭代器include/pybind11/pybind11.hmake_key_iteratorpybind11.h与make_value_iteratorpybind11.h分别迭代容器的键与值。三者的底层统一走detail::make_iterator_implpybind11.h通过iterator_access/iterator_key_access/iterator_value_access三种访问策略区分取值方式。Extra...用于传递return_value_policy、keep_alive等额外策略参数。make_key_iterator/make_value_iterator被大量用于容器绑定例如 include/pybind11/stl_bind.h 中为 map 绑定实现的iter()键迭代器与值迭代器配合使map.items()、map.keys()、map.values()在 Python 侧行为正确。Passing extra arguments todef或py::class_注解参数组reference.rst 的_extras锚点对应doxygengroup:: annotations即传给m.def(...)或py::class_...(...)的“额外参数”家族全部定义于 include/pybind11/attr.h。常用成员包括arg(name)、arg_v(name, value)命名参数与带默认值的命名参数arg_v的简写py::arg(x) valuereturn_value_policy控制返回值所有权核心枚举定义于 include/pybind11/detail/common.h如take_ownership、copy、move、reference、reference_internal、automatic等keep_aliveNurse, Patient保证护士对象在病人对象存续期间不被回收call_guardT()如call_guardpy::gil_scoped_release()在调用期间临时释放 GILdoc、is_method、is_operator等描述性注解。这些注解最终被detail::process_attributes等内部机制解析写入函数的function_record从而影响参数解析、默认值、文档字符串与生命周期管理。Embedding the interpreter在 C 中嵌入 Pythonreference.rst 的“Embedding the interpreter”章节涵盖四个 API全部位于 include/pybind11/embed.hPYBIND11_EMBEDDED_MODULE(name, variable, ...)embed.h注册嵌入式模块用法与PYBIND11_MODULE一致第三参数同样支持py::mod_gil_not_used()等见 embed.h但适用于静态链接场景initialize_interpreter()启动解释器。支持两个重载接受PyConfig*、argc/argv与add_program_dir_to_path的完整版本embed.h以及默认init_signal_handlers true的便捷版本embed.h除PYBIND11_EMBEDDED_MODULE外任何 pybind11 调用前都必须先初始化embed.hfinalize_interpreter()关闭解释器之后可通过再次initialize_interpreter重启embed.hscoped_interpreterRAII 作用域守卫构造时初始化、析构时终结解释器embed.h异常安全且避免忘记终结。配套用法示例scoped_interpreter的典型生命周期是“构造 → 用py::exec或导入模块执行 Python 代码 → 析构自动回收”参见 docs/advanced/pycpp/utilities.rst。仓库的测试入口 tests/test_interpreter.cpp 与 tests/test_with_catch/test_interpreter.py 提供了嵌入/终结解释器及子解释器行为的具体验证用例。Redirecting C streams把std::cout重定向到 Pythonreference.rst 列出三个流重定向 API实现于 include/pybind11/iostream.hscoped_ostream_redirectiostream.h作用域内把std::cout/std::cerr可选通过构造参数指定重定向到 Python 的sys.stdoutscoped_estream_redirectiostream.h继承自scoped_ostream_redirect专门重定向std::cerr到sys.stderradd_ostream_redirectiostream.h给模块注册名为ostream_redirect可自定义的上下文管理器Python 侧可写with m.ostream_redirect(): ...。scoped_ostream_redirect支持第二个模板参数指定回调如“刷新”策略内部维护detail::pythonbuf这类 streambuf 适配器把 C 流缓冲写入sys.stdout/sys.stderr的write/flush。典型场景是让 C/C 库的printf/std::cout输出在 Jupyter Notebook 或 GUI 应用中实时出现在 Python 侧。参考实现在 docs/advanced/pycpp/utilities.rst 中有介绍iostream.h头部注释也给出了py::add_ostream_redirect(m)的用法对应测试见 tests/test_iostream.cpp 与 tests/test_iostream.py。Python built-in functions 与 Inheritance虚函数覆盖python_builtins组reference.rst 的doxygengroup:: python_builtins指向 include/pybind11/pybind11.h 中的一组内建函数包装例如py::print(...)把参数打印到sys.stdout支持sep/end/file等关键字、py::exec/py::eval执行/求值 Python 表达式相关实现见 include/pybind11/eval.h以及py::len、py::getattr、py::setattr、py::hasattr等。它们让 C 侧能像写 Python 一样操作解释器。虚函数覆盖宏与get_overrideInheritance 章节指向 docs/classes.rst 与 docs/advanced/classes.rst 获取完整说明同时列出四个宏与一个函数均用于在 trampoline跳板类中把 C 虚函数调用转发回 Python 覆盖方法定义于 include/pybind11/pybind11.hPYBIND11_OVERRIDE(ret_type, cname, fn, ...)按成员函数名查找 Python 侧同名覆盖PYBIND11_OVERRIDE_PURE(ret_type, cname, fn, ...)纯虚函数版本PYBIND11_OVERRIDE_NAME(ret_type, cname, name, fn, ...)显式指定 Python 侧方法名namePYBIND11_OVERRIDE_PURE_NAME(ret_type, cname, name, fn, ...)纯虚 显式命名get_override(const T obj, const char *name)在 trampoline 中手动获取 Python 覆盖方法的function对象供高级定制使用。典型 trampoline 写法struct PyDog : Dog { std::string bark() const override { PYBIND11_OVERRIDE(std::string, Dog, bark); } };这些宏在仓库中的落地验证见 tests/test_virtual_functions.cpp虚函数/覆盖测试与 tests/test_multiple_inheritance.cpp。其底层依赖detail::get_function_record与internals中缓存的函数记录来定位 Python 方法。Exceptions异常体系与Literals命名空间异常类型reference.rst 的 Exceptions 章节引用两个类均定义于 include/pybind11/pybind11.herror_already_set当 Python 解释器已经设置异常PyErr_Occurred()非空时由 pybind11 抛出用于把 Python 异常安全地传递回 C 层析构/处理时会调用PyErr_Fetch语义恢复或重抛。它是 GIL 边界异常传递的关键载体。builtin_exception内建异常的公共基类py::stop_iteration、py::index_error、py::key_error、py::value_error、py::type_error、py::buffer_error、py::import_error、py::attribute_error等类型化异常均派生自它让 C 可以按类型捕获 Python 内建异常。异常处理与转换的完整机制register_exception、translate_exception等见 include/pybind11/detail/exception_translation.h仓库测试见 tests/test_exceptions.cpp 与 tests/test_exceptions.py。literals命名空间reference.rst 最后一节doxygengroup:: literals对应pybind11::literals命名空间提供用户自定义字面量操作符典型如using namespace pybind11::literals; m.def(add, add, a_a, b_a);其中name_a是py::arg(name)的简写用于在def/class_调用中快速声明命名参数。实现位于 include/pybind11/attr.h 的literals子命名空间operator_a。结语如何继续深入这份参考docs/reference.rst的价值在于把 pybind11 的公开 API 组织成一张可跳转的索引地图而其内容最终都落在头文件中。后续深入路径建议类型体系细节 → 通读 include/pybind11/pytypes.h模块注册与特性宏 → include/pybind11/detail/common.h嵌入解释器 → include/pybind11/embed.h流重定向 → include/pybind11/iostream.h注解与字面量 → include/pybind11/attr.h完整使用教程 → docs/classes.rst、docs/advanced/classes.rst、docs/advanced/pycpp/utilities.rst。结合本仓库的 tests 目录中成对的.cpp/.py测试文件如 tests/test_virtual_functions.cpp tests/test_virtual_functions.py可以对上述每个 API 找到可直接运行验证的实例。【免费下载链接】pybind11Seamless operability between C11 and Python项目地址: https://gitcode.com/GitHub_Trending/py/pybind11创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
