如何将我的Python C模块放入包中



我想在一个包下收集多个 Python 模块,这样它们就不会从全局的 python 包和模块集中保留太多名称。但是我对用 C 编写的模块有问题。

这是一个非常简单的例子,直接来自官方的Python文档。您可以从此处在页面底部找到它:http://docs.python.org/distutils/examples.html

from distutils.core import setup
from distutils.extension import Extension
setup(name='foobar',
      version='1.0',
      ext_modules=[Extension('foopkg.foo', ['foo.c'])],
      )

我的 foo.c 文件看起来像这样

#include <Python.h>
static PyObject *
foo_bar(PyObject *self, PyObject *args);
static PyMethodDef FooMethods[] = {
    {
        "bar",
        foo_bar,
        METH_VARARGS,
        ""
    },
    {NULL, NULL, 0, NULL}
};
static PyObject *
foo_bar(PyObject *self, PyObject *args)
{
    return Py_BuildValue("s", "foobar");
}
PyMODINIT_FUNC
initfoo(void)
{
    (void)Py_InitModule("foo", FooMethods);
}
int
main(int argc, char *argv[])
{
    // Pass argv[0] to the Python interpreter
    Py_SetProgramName(argv[0]);
    // Initialize the Python interpreter.  Required.
    Py_Initialize();
    // Add a static module
    initfoo();
    return 0;
}

它构建和安装正常,但我无法导入 foopkg.foo!如果我将其重命名为"foo",它可以完美运行。

任何想法如何使"foopkg.foo"工作?例如,将 "foo" 从 C 代码中的 Py_InitModule() 更改为 "foopkg.foo" 是没有帮助的。

foopkg 文件夹中必须有一个__init__.py文件,否则 Python 无法识别为包。

setup.py所在的位置创建一个foopkg文件夹,并在其中放置一个空文件__init__.py,并在setup.py中添加一个packages行:

from distutils.core import setup
from distutils.extension import Extension
setup(name='foobar',
      version='1.0',
      packages=['foopkg'],
      ext_modules=[Extension('foopkg.foo', ['foo.c'])],
      )

distutils将从 Python 3.10 开始被弃用,而是您可以使用 setuptools ,这是distutils的增强替代方案,因此您无需在setup()中传递packages参数。例如:

from setuptools import setup, Extension
setup(name='foobar',
      version='1.0',
      ext_modules=[Extension('foopkg.foo', ['foo.c'])],
      )

然后构建并安装 C 扩展

python /PATH/TO/setup.py install

成功构建 C 扩展后,通过运行以下命令测试是否可以按预期导入它:

python -c "from foopkg import foo"

[旁注]关于setuptool的另一件事是,您可以通过简单地运行pip uninstall来卸载C扩展包,例如:python -m pip uninstall foobar

最新更新