在一个共享对象中提升 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
上面的例子工作正常。
我正在尝试通过 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
上面的例子工作正常。