<p>从<a href="https://www.python.org/dev/peps/pep-0489/#multiple-modules-in-one-library" rel="nofollow noreferrer">https://www.python.org/dev/peps/pep-0489/#multiple-modules-in-one-library</a>引用:</p>
<blockquote>
<p>To support multiple Python modules in one shared library, the library can export additional PyInit* symbols <strong>besides the one that corresponds to the library's filename</strong>.</p>
<p>Note that this mechanism can currently only be used to <strong>load</strong> extra modules, <strong>but not to find them</strong>. (This is a limitation of the loader mechanism, which this PEP does not try to modify.) ...</p>
</blockquote>
<p>换句话说,您需要按如下方式重新构造项目<code>importlib</code>,以便能够在<code>sysipc</code>包中找到子模块<code>light</code>:</p>
<pre><code>company/__init__.py
company/dept/__init__.py
company/dept/sys/__init__.py
company/dept/sys/sysipc/__init__.py
company/dept/sys/sysipc/sysipc.so
company/dept/sys/sysipc/light.so -> sysipc.so # hardlink
</code></pre>
<p><code>light.so</code>和<code>sysipc.so</code>之间的硬链接可以通过以下方式创建:</p>
<pre><code>ln company/dept/sys/sysipc/sysipc.so company/dept/sys/sysipc/light.so
</code></pre>
<p>然后在<code>company/dept/sys/sysipc/__init__.py</code>中,使用以下方法从<code>sysipc.so</code>导入所有符号:</p>
<pre><code>from .sysipc import *
</code></pre>
<p>此外,对于Python2,需要将子模块C扩展init函数的名称从<code>init_sysipc_light</code>更改为<code>init_light</code>,对于Python3,需要将子模块C扩展init函数的名称从<code>PyInit_sysipc_light</code>更改为<code>PyInit_light</code>,因为<code>importlib</code>通过从动态模块中查找导出的<code>PyInit_<module name></code>来加载模块,并且这里的模块名称仅为<code>light</code>,即。,父包前缀不是(子)模块名称的一部分</p>
<p>以下是扩展代码(Python3)和两个用于测试的函数:</p>
<pre><code>#include <Python.h>
PyObject *sysipc_light_foo(PyObject *self, PyObject *args) {
printf("[*] sysipc.light.foo\n");
return PyLong_FromLong(0);
}
static PyMethodDef sysipc_light_methods[] = {
{"foo", (PyCFunction)sysipc_light_foo, METH_VARARGS, "sysipc.light.foo function"},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef sysipc_light_module = {
PyModuleDef_HEAD_INIT,
"sysipc.light",
"sysipc child module",
-1,
sysipc_light_methods
};
PyMODINIT_FUNC PyInit_light(void)
{
PyObject *module = NULL;
module = PyModule_Create(&sysipc_light_module);
return module;
}
PyObject *sysipc_bar(PyObject *self, PyObject *args) {
printf("[*] sysipc.bar\n");
return PyLong_FromLong(0);
}
static PyMethodDef sysipc_methods[] = {
{"bar", (PyCFunction)sysipc_bar, METH_VARARGS, "sysipc.bar function"},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef sysipc_module = {
PyModuleDef_HEAD_INIT,
"sysipc",
"sysipc parent module",
-1,
sysipc_methods
};
PyMODINIT_FUNC PyInit_sysipc(void)
{
PyObject *module = NULL;
module = PyModule_Create(&sysipc_module);
PyInit_light();
return module;
}
</code></pre>
<p>test.py:</p>
<pre><code>#!/usr/bin/env python3
from company.dept.sys import sysipc
from company.dept.sys.sysipc import light
sysipc.bar()
light.foo()
</code></pre>
<p>输出:</p>
<pre><code>[*] sysipc.bar
[*] sysipc.light.foo
</code></pre>