2012-06-16 2 views
3

У меня есть модуль modA, который содержит синтезированный подмодуль modB (созданный с помощью PyModule_New); импортирует модуль:синтезированный подмодуль: от импорта В (ok) против импорта A.B (ошибка)?

  1. from modA import modB это нормально
  2. import modA.modB терпит неудачу.

Что мне не хватает?

  • modA.cpp (с использованием boost::python, но это было бы весьма вероятно, то же самое с чистым с-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 *.

Смежные вопросы