我有一个模块modA
,其中包含一个合成子模块modB
(使用PyModule_New
创建);现在导入模块:
from modA import modB
没关系import modA.modB
失败。我错过了什么?
modA.cpp(使用boost::python
,但它很可能与python的纯c-API相同):
#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`
test.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
答案 0 :(得分:1)
感谢this answer,我找到了解决方案,该解决方案包含在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;
};
答案 1 :(得分:1)
这是我使用的模式,希望它能改善以前的答案......
module.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();
...
module.cpp:
BOOST_PYTHON_MODULE(modulename)
{
export_submodule();
}
submodule.cpp:
export_submodule()
{
// create submodule
MAKE_SUBMODULE(modulename, submodulename)
// all code below is now in submodule's scope
...
}
&#34;生成&#34;代码如下所示:
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 *
语句正常工作。
答案 2 :(得分:0)
modB
不是文件(即模块),而是modA
中的某个对象,因此无法导入。
您可能希望看到Python's modules docs。