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

使用Pybind11跨文件导入模块时遭遇ModuleNotFoundError

问题分析与解决

你的问题核心在于编译方式错误,导致base_class模块并未实际生成,而derived_class绑定代码里又尝试导入这个不存在的模块,从而触发ModuleNotFoundError。另外你的C++代码还有几处语法错误需要修正。

第一步:修正C++代码中的语法问题

  1. base_class.h:修复构造函数初始化列表语法,补充类定义末尾分号
// base_class.h
class BaseClass {
    public:
        BaseClass(int id): id(id) {} // 移除多余的int关键字
        int get_id() { return id; }
    private:
        int id;
}; // 类定义末尾必须添加分号
  1. derived_class.h:修正头文件引用路径并补充分号
// derived_class.h
#include "common/base_class.h" // 补充.h后缀,路径需匹配实际文件结构

class DerivedClass: public BaseClass {
    public:
        DerivedClass(int id);
}; // 类定义末尾添加分号

第二步:拆分编译,生成独立扩展模块

按照pybind11跨模块拆分的设计要求,你需要分别编译base_class和derived_class两个独立的共享对象文件:

编译base_class模块

g++ -std=c++20 -shared -fpic `python3.12 -m pybind11 --includes` common/base_class_binding.cpp -o base_class.so

编译derived_class模块

g++ -std=c++20 -shared -fpic `python3.12 -m pybind11 --includes` derived_class.cpp derived_class_binding.cpp -o derived_class.so

第三步:调整Python测试代码

确保生成的两个.so文件和test.py在同一目录下,修改测试代码如下(显式导入基类模块可避免导入顺序问题):

# test.py
import base_class
from derived_class import DerivedClass

if __name__ == '__main__':
    derived_obj = DerivedClass(1)
    print(f'The ID is: {derived_obj.get_id()}')

为什么之前的方法行不通?

  1. 错误的编译命令:你把base_class_binding.cpp和derived_class的代码打包到同一个.so中,但每个PYBIND11_MODULE会生成独立的Python模块入口,这会导致两个模块定义冲突,最终只有derived_class模块被识别,base_class模块根本不存在,自然无法导入。
  2. 重复定义基类绑定:虽然重复定义py::class_<BaseClass>能临时运行,但违背了跨模块拆分的初衷,会带来代码冗余和维护隐患。

额外注意事项

  • 如果两个.so不在Python默认搜索路径,需手动添加路径:
    import sys
    sys.path.append("/path/to/your/modules")
    
  • 绑定代码中py::module_::import("base_class")的模块名必须和生成的.so文件名完全一致(大小写敏感)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:27:06