ImportError: el módulo dinámico no define la función init (initfizzbuzz)


Traté de compilar fizzbuzz.c para importar desde python. Para construir fizzbuzz.c, utilicé python setup.py build_ext -i.

Después de construirlo, traté de importar fizzbuzz.c pero se produjo el error a continuación. ¿Cómo puedo resolver este problema ?

Error

>>> import fizzbuzz
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initfizzbuzz)

Fizzbuzz.c

#include <stdio.h>

void fizzbuzz(int n){

    for (int i=1; i <= n; i++){
        if (i % 3 == 0 && i % 5 ==0){
            printf("fizzbuzz %d \n", i);
        }
        else if (i % 3 == 0){
            printf("fizz %d \n", i);
        }
        else if(i % 5 == 0){
            printf("buzz %d \n", i);
        }
    }
}

Setup.py

from distutils.core import setup, Extension
module = Extension('fizzbuzz', ['fizzbuzz.c'])
setup(
      name='fizzbuzz',
      version='1.0',
      ext_modules=[module],
)
Author: SamuraiT, 2014-06-15

6 answers

Python no soporta y no puede soportar archivos C arbitrarios como módulos. Tendrás que seguir ciertas convenciones para que Python sepa qué funciones soporta tu módulo.

Para hacerlo, Python buscará una función init<name>, donde <name> es el nombre del módulo. Python estaba buscando initfizzbuzz pero no pudo encontrarlo, por lo que falló la carga del módulo.

Además de un inicializador, también debe proporcionar una estructura que detalle qué funciones están disponibles, y su función deberá manejar Python escribe como argumentos. Python le proporciona las funciones de utilidad necesarias y define para hacer que sea lo suficientemente fácil.

Le recomiendo encarecidamente que siga el Extendiendo e incrustando el tutorial del Intérprete de Python. Te enseña todo lo que necesitas saber para hacer que tu código C fizzbuzz funcione como un módulo Python.

 19
Author: Martijn Pieters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-15 02:27:33

El error también ocurre cuando se usa boost::python, si el nombre del módulo es diferente al nombre del archivo compiled .so. Por ejemplo:

Hola.cpp

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace std;
using namespace boost::python;

int helloWorld(){
    cout << "Hello world!" << endl;
    return 0;
}

BOOST_PYTHON_MODULE(libhello) {
    def("hello_world", helloWorld);
}

Orden de compilación:

g++ -fpic -shared -o libfoo.so -Wl,-soname,"libfoo.so" hello.cpp -I<path/to/python> -L/usr/local/lib  -lboost_python-py34

Cuando se incluye en python con import libfoo se produce el siguiente error:

ImportError: dynamic module does not define init function (PyInit_libfoo)

Esto se debe a que "libhello" y "libfoo" no coinciden.

 43
Author: philosopher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-28 10:44:21

Worth notify - el mismo error puede ocurrir si la biblioteca se compila para diferentes versiones de python. Por ejemplo, si shared object es para python 3, pero intenta importar módulo desde python 2.

 16
Author: Ivan Klass,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-05 11:26:43

Debe definir una función llamada init_fizzbuzz, que debe contener el código para inicializar el módulo. Esta función también debería llamar a Py_InitModule, para configurar los enlaces para las funciones c en Python. Para más información, echa un vistazo a este tutorial.

En su caso, su código debe adaptarse a algo como esto:

static PyObject* py_fizzbuzz(PyObject* self, PyObject* args)
{
    int value;
    if (!PyArg_ParseTuple(args, "i", &value))
        return NULL;
    for (int i=1; i <= n; i++){
        if (i % 3 == 0 && i % 5 ==0){
            printf("fizzbuzz %d \n", i);
            }
        else if (i % 3 == 0){
            printf("fizz %d \n", i);
            }
        else if(i % 5 == 0){
            printf("buzz %d \n", i);
            }
        }

    // Return value.
    return Py_BuildValue("i", 0);

}

// Mapping between python and c function names. 
static PyMethodDef fizzbuzzModule_methods[] = {
    {"fizzbuzz", py_fizzbuzz, METH_VARARGS},
    {NULL, NULL}
    };

// Module initialisation routine.
void init_fizzbuzz(void)
{
    // Init module.
    (void) Py_InitModule("fizzbuzz", fizzbuzzModule_methods);

}
 5
Author: lackadaisical,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-01 00:56:34

Si usas python 3 entonces necesitas tener los siguientes cambios en tu código,

static struct PyModuleDef fizzbuzzModuleDef =
{
    PyModuleDef_HEAD_INIT,
    "fizzbuzz", /* name of module */
    "",          /* module documentation, may be NULL */
    -1,          /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
    fizzbuzzModule_methods
};

PyMODINIT_FUNC PyInit_exmod(void) {
    return PyModule_Create(&fizzbuzzModuleDef);
}
 1
Author: kar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-10 21:26:32

Hacer python3 ./ yourpythonscript

En lugar de

Python ./ yourpythonscript

Incluso si tienes python alias como python3

El nombre debe ser exacto con el que compile boost y boost-python: brew reinstall boost with con-python3 without sin-python brew reinstall boost-python with with-python3 without without-python

 0
Author: Aditya Mittal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-07 08:24:54