Как построить расширение Python C, чтобы я мог импортировать его из модуля - программирование
Подтвердить что ты не робот

Как построить расширение Python C, чтобы я мог импортировать его из модуля

У меня есть проект Python со многими подмодулями, которые я упаковываю с distutils. Я хотел бы построить некоторые расширения Python в C, чтобы жить в некоторых из этих подмодулей, но я не понимаю, как заставить расширение 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);
}

И вот работает 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'])])

После установки в virtualenv я могу сделать это:

>>> import c_extension
>>> c_extension.get_answer()
42

Но я хотел бы иметь c_extension жить в подмодуле, скажем foo.bar. Что мне нужно изменить в этом конвейере, чтобы иметь возможность заставить поведение в оболочке Python выглядеть следующим образом:

>>> import foo.bar.c_extension
>>> foo.bar.c_extension.get_answer()
42
4b9b3361

Ответ 1

Просто измените

Extension('c_extension', ...)

к

Extension('foo.bar.c_extension', ...)

Вам понадобятся файлы __init__.py в каждом каталоге foo и bar, как обычно. Чтобы они были упакованы вместе с модулем в файле setup.py, вам нужно добавить

packages = ['foo', 'foo.bar'],

к вызову setup(), и вам понадобится структура каталогов

setup.py
foo/
    __init__.py
    bar/
        __init__.py

в исходном каталоге.