имя функции инициализации собственного модуля python

#python #cpython #python-c-api

#python #cpython #python-c-api

Вопрос:

Итак, я пытаюсь создать модуль привязки python на C, но запутался в том, что такое правило именования функции инициализации модуля, которая объявлена PyMODINIT_FUNC , я видел init_foo , и initfoo , и кто-то еще использует PyInit_foo , имеет ли значение имя? какому из них я должен следовать?

 PyMODINIT_FUNC void init_foo(void) {...}
PyMODINIT_FUNC void initfoo(void) {...}
PyMODINIT_FUNC void PyInit_foo(void) {...}
  

Ответ №1:

Из расширяющих Python документов на C или C (Python3),

Функция инициализации должна иметь имя PyInit_name() , где name — это имя модуля, и должна быть единственным нестатическим элементом, определенным в файле модуля:

 PyMODINIT_FUNC
PyInit_spam(void)
{
    return PyModule_Create(amp;spammodule);
}
  

Вы также можете найти один и тот же шаблон во всем исходном коде cpython (python3)

Тогда как при расширении Python с помощью C или C docs (Python2)

Функция инициализации должна иметь имя initname() , где name — это имя модуля, и должна быть единственным нестатическим элементом, определенным в файле модуля:

 PyMODINIT_FUNC
initspam(void)
{
    (void) Py_InitModule("spam", SpamMethods);
}
  

Итак, чтобы ответить на ваш вопрос, имя имеет значение. Если вы пишете расширение, совместимое как с python2, так и с python3, вы должны реализовать инициализацию модуля следующим образом,

 #if PY_MAJOR_VERSION < 3
    PyMODINIT_FUNC
    init_modulename(void)
    {
        return yourmoduleinit();
    }
#else
    PyMODINIT_FUNC
    PyInit_modulename(void)
    {
        return yourmoduleinit();
    }
#endif
  

Примечание: PyMODINIT_FUNC void init_foo(void) {...} на самом деле это версия python2, и имя модуля, используемое для импорта этого c-расширения, будет _foo использоваться для обозначения [внутреннего c-расширения]