在一个共享对象中提升 python 个多个模块

Boost python multiple modules in one shared object

我正在尝试通过 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();
    .
    .
    .

}

此代码有效。

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

这当然不能接受。 (考虑到加载单个模块可能会消耗 1-3MB 的内存)

在 python 时,如果我调用:

from myPackage.myModule import *

from myPackage.myModule import someClass

内存消耗立即飙升至 65MB。

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

from myPackage.myModule import class1
c = class2()

我得到一个错误:

NameError: name 'class2' is not defined

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

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

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

上面的代码也适用于以下形式的调用:

from myPackage.myModule import class1
c = class2()

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

将共享对象放入正确的站点包文件夹后, 这当然有 __init__.py 上面的例子工作正常。