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

时间:2012-10-12 10:17:08

标签: python distutils python-module

我想在一个包下收集多个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”工作的?例如,将C代码中的Py_InitModule()中的“foo”更改为“foopkg.foo”没有用。

2 个答案:

答案 0 :(得分:6)

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

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

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'])],
      )

答案 1 :(得分:0)

distutils will be deprecated since python 3.10 ,而您可以使用 setuptools,它是 distutils 的增强替代品,因此您无需在 {{1} 中传递 packages 参数}}。例如:

setup()

然后构建并安装您的 C 扩展

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

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