在一个共享对象中增加python多个模块

Max*_*rin 6 c++ python boost python-2.6 boost-python

我正在尝试通过boost python创建一个包含几个模块的包.

原因是我们希望公开一个非常大的API,将它组合在不同的模块中以便于使用和保留python内存使用是有意义的.另一方面,我们被迫(由于超出此问题范围的原因将其编译为单个共享对象)

所以我用boost python创建了一个导出几个模块的包,如下所示:

void exportClass1()
{
    namespace bp = boost::python;
    // map the IO namespace to a sub-module
    // make "from myPackage.class1 import <whatever>" work
    bp::object class1Module(bp::handle<>(bp::borrowed(PyImport_AddModule("myPackage.class1"))));
    // make "from mypackage import class1" work
    bp::scope().attr("class1") = class1Module;
    // set the current scope to the new sub-module
    bp::scope io_scope = class1Module;

    // export stuff in the class1 namespace

    class_<class1 >("class1", init<>())
    .
    .   CLASS SPECIFICS GO HERE
    .

    Other class of module class1 go here as well
}

BOOST_PYTHON_MODULE(myPackage)
{
    namespace bp = boost::python;

    // specify that this module is actually a package
    bp::object package = bp::scope();
    package.attr("__path__") = "myPackage";

    exportClass1();
    exportClass2();
    .
    .
    .

}
Run Code Online (Sandbox Code Playgroud)

这段代码有效.

主要问题是内存消耗.整个暴露的api 非常大,所以加载整个包装消耗大约65MB的ram,仅用于所有声明.(在包用户开始做任何事情之前)

这当然是不可接受的.(假设加载单个模块应该消耗1-3MB的RAM)

在python中,如果我打电话:

from myPackage.myModule import *
Run Code Online (Sandbox Code Playgroud)

要么

from myPackage.myModule import someClass
Run Code Online (Sandbox Code Playgroud)

内存消耗量急剧上升至65MB.

在执行任何导入后,如果我调用:sys.modules我看到我的包中的所有类都是"已知"但是如果我运行:

from myPackage.myModule import class1
c = class2()
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

NameError:未定义名称"class2"

所以我似乎得到了两个世界中最糟糕的一方面,一方面我消耗内存,好像我从包中导入了所有东西,另一方面我没有得到实际导入的类.

任何想法如何解决这个问题,这样当我导入一个特定的模块时,它只会被导入,而不是所有的包数据都会被读取到python内存中.(这既花费时间又消耗了大量宝贵的记忆)

Max*_*rin 3

所以这比我想象的要简单得多。

上面的代码对于以以下形式进行调用也是正确的:

from myPackage.myModule import class1
c = class2()
Run Code Online (Sandbox Code Playgroud)

阻止正确执行的是系统路径。__init__.py共享对象未放置在 python 路径的位置,并且在放置它的文件夹中没有。

一旦共享对象被放置在正确的站点包文件夹中,__init__.py上面的示例当然可以正常工作。