2012-06-16 31 views
3

我有一個模塊modA,它包含一個子模塊合成modB(與PyModule_New創建);現在導入模塊:合成子模塊:從A導入B(ok)與導入A.B(錯誤)?

  1. from modA import modB這是確定
  2. import modA.modB失敗。

我錯過了什麼?

  • modA.cpp(使用boost::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; 
    }; 
    
  • 編譯(代替鐺克++ ++的工作原理相同)

    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

您應該添加您的解決方案作爲一個答案,並接受它。 –

+0

我剛剛那樣做,謝謝你的建議。必須等待2天才能接受:-) – eudoxos

回答

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; 
}; 
0

modB不是文件(即一個模塊),但modA中的某個對象,因此無法導入。

您可能希望看到Python's modules docs

+0

'modB'是一個模塊,它恰好在飛行中創建。 – eudoxos

+0

我不明白。請指定 - 是'modB'文件還是不是? – Vidul

+0

不,'modB'是在運行時創建的模塊對象。 – eudoxos

1

下面是我用的模式,希望它改善了以前的答案...

module.h中:

... 
#define STR(str) #str 
#define MAKE_SUBMODULE(mod, submod) object mod_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 
    ... 
} 

的 「生成」 的代碼如下所示:

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

它類似於eudoxos答案,但differencs似乎是在細節:而不是PyImportNew()我使用PyImportAdd()。因此,我不需要最後一行來獲得from module.submodule import *聲明的工作。