如何构建Python C扩展,以便我可以从模块中导入它

Ric*_*ich 19 python distutils python-extensions

我有一个包含许多子模块的Python项目,我用distutils打包.我想在C中构建一些Python扩展以存在于其中一些子模块中,但我不明白如何使Python扩展存在于子模块中.以下是我正在寻找的最简单的例子:

这是我的Python扩展c_extension.c:

#include <Python.h>

static PyObject *
get_answer(PyObject *self, PyObject *args)
{
    return Py_BuildValue("i", 42);
}

static PyMethodDef Methods[] = {
    {"get_answer",  get_answer, METH_VARARGS, "The meaning of life."},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
initc_extension(void) {
  (void) Py_InitModule("c_extension", Methods);
}
Run Code Online (Sandbox Code Playgroud)

以下setup.py是有效的:

from distutils.core import setup
from distutils.extension import Extension

setup(name='c_extension_demo',
      ext_modules = [Extension('c_extension', sources = ['c_extension.c'])])
Run Code Online (Sandbox Code Playgroud)

在virtualenv中安装后我可以这样做:

>>> import c_extension
>>> c_extension.get_answer()
42
Run Code Online (Sandbox Code Playgroud)

但是,我想c_extension生活在一个子模块中foo.bar.我需要在此管道中进行哪些更改才能使Python shell中的行为如下所示:

>>> import foo.bar.c_extension
>>> foo.bar.c_extension.get_answer()
42
Run Code Online (Sandbox Code Playgroud)

nne*_*neo 14

只是改变

Extension('c_extension', ...)
Run Code Online (Sandbox Code Playgroud)

Extension('foo.bar.c_extension', ...)
Run Code Online (Sandbox Code Playgroud)

您将需要__init__.py的文件在每个的foobar目录,一如往常.要将这些包装在setup.py中的模块中,您需要添加

packages = ['foo', 'foo.bar'],
Run Code Online (Sandbox Code Playgroud)

到你的setup()调用,你将需要目录结构

setup.py
foo/
    __init__.py
    bar/
        __init__.py
Run Code Online (Sandbox Code Playgroud)

在您的源目录中.

  • 不要从源目录进行测试.这将尝试从没有c_extension的源目录中的foo/bar导入. (5认同)