You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用pybind11在两个不同子模块中导出同一类型?

报错原因

pybind11 对每个唯一的C类型全局仅允许做一次py::class_绑定注册,重复注册同一类型就会触发type is already registered错误。
示例代码中NS2::S1是通过using声明引入的NS1::S1别名,二者在C
层面是完全相同的类型,两次调用py::class_注册同一个类型必然触发报错。

正确实现方案

只需要在第一个子模块完成一次S1类型的注册,拿到绑定生成的Python类型对象后,直接将该对象赋值给第二个子模块的同名属性即可,不需要重复执行类型绑定逻辑。这种写法下两个子模块导出的S1是完全同一个Python类型,完全匹配需求。

正确绑定代码:

PYBIND11_MODULE(my_module, m) {
  py::module_ m1 = m.def_submodule("NS1", "");
  py::module_ m2 = m.def_submodule("NS2", "");

  // 仅在NS1子模块注册一次S1类型
  auto s1_cls = py::class_<NS1::S1>(m1, "S1");
  // 将同一个类型对象挂载到NS2子模块的S1属性
  m2.attr("S1") = s1_cls;

  py::class_<NS2::S2>(m2, "S2");
}
Python侧行为验证

编译完成后Python侧调用效果完全符合预期:

import my_module

# 两个子模块的S1为完全相同的类型
assert my_module.NS1.S1 is my_module.NS2.S1

# 类型判断、实例化逻辑正常
obj = my_module.NS1.S1()
assert isinstance(obj, my_module.NS2.S1)

内容的提问来源于stack exchange,提问作者Nicola Gigante

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 20:06:27