3

我有一个 module modA,其中包含一个合成的子模块modB(用 创建PyModule_New);现在导入模块:

  1. from modA import modB没关系
  2. import modA.modB失败。

我错过了什么?

  • modA.cpp (使用boost::python,但很可能与纯 c-API 的 python 相同):

    #include<boost/python.hpp>
    namespace py=boost::python;
    
    BOOST_PYTHON_MODULE(modA){
       py::object modB=py::object(py::handle<>(PyModule_New("modB")));
       modB.attr("__file__")="<synthetic>";
       py::scope().attr("modB")=modB;
    };
    
  • 用 (g++ 而不是 clang++ 的工作方式相同) 编译

    clang++ -o modA.so modA.cpp -fPIC -shared  -lboost_python `pkg-config python --cflags --libs`
    
  • 测试.py:

    import sys
    sys.path.append('.')
    from modA import modB
    import modA.modB
    
  • python test.py(注意第一次导入很好,第二次导入失败):

    Traceback (most recent call last):
      File "test.py", line 4, in <module>
        import modA.modB
    ImportError: No module named modB
    
4

3 回答 3

1

感谢这个答案,我找到了解决方案,它包含在sys.modules['modA.modB']=modB模块初始化函数中,但用c++编写:

#include<boost/python.hpp>
namespace py=boost::python;

BOOST_PYTHON_MODULE(modA){
   py::object modB=py::object(py::handle<>(PyModule_New("modA.modB")));
   modB.attr("__file__")="<synthetic>";
   py::scope().attr("modB")=modB;

   // this was the missing piece: sys.modules['modA.modB']=modB
   py::extract<py::dict>(py::getattr(py::import("sys"),"modules"))()["modA.modB"]=modB;
};
于 2012-06-16T12:36:49.637 回答
1

这是我使用的模式,希望它能改善以前的答案......

模块.h:

...
#define STR(str) #str
#define MAKE_SUBMODULE(mod, submod) object submod##_module(handle<>(borrowed(PyImport_AddModule(STR(mod.submod)))));\
scope().attr(STR(submod)) = submod##_module;\
scope submod##_scope = submod##_module;\
...
export_submodule();
...

模块.cpp:

BOOST_PYTHON_MODULE(modulename)
{
    export_submodule();
}

子模块.cpp:

export_submodule()
{
    // create submodule
    MAKE_SUBMODULE(modulename, submodulename)

    // all code below is now in submodule's scope
    ...
}

“生成”的代码如下所示:

object submodulename_module(handle<>(borrowed(PyImport_AddModule("modulename.submodulename"))));
scope().attr("submodulename") = submodulename_module;
scope submodulename_scope = submodulename_module;

它看起来类似于 eudoxos 答案,但差异似乎很详细:而不是PyImportNew()我使用PyImportAdd(). 因此,我不需要最后一行来使from module.submodule import *语句生效。

于 2015-01-24T23:27:51.563 回答
0

modB不是文件(即模块),而是 中的某个对象modA,因此无法导入。

您可能想查看Python 的模块文档

于 2012-06-16T12:25:35.960 回答