ejemplo canónico de un programa extending embedded Python 3.x en C/C++:¿Hace PyImport_ImportModule e importa la instrucción de carga en diferentes espacios de nombres? Aquí es
#include <Python.h>
//// Definition of 'emb' Python module ////////////////////
static PyObject* emb_foo(PyObject *self, PyObject *args)
{
char const* n = "I am foo";
return Py_BuildValue("s", n);
}
static PyMethodDef EmbMethods[] = {
{"foo", emb_foo, METH_VARARGS, "Returns foo"},
{NULL, NULL, 0, NULL}
};
static PyModuleDef EmbModule = {
PyModuleDef_HEAD_INIT, "emb", NULL, -1, EmbMethods,
NULL, NULL, NULL, NULL
};
static PyObject* PyInit_emb(void)
{
return PyModule_Create(&EmbModule);
}
//// Embedded Python with 'emb' loaded ////////////////////
int main()
{
PyImport_AppendInittab("emb", &PyInit_emb);
Py_Initialize();
PyRun_SimpleString("import emb\n"); // (1)
//PyImport_ImportModule("emb"); // (2)
PyRun_SimpleString("print(emb.foo())\n"); // (3)
Py_Finalize();
return 0;
}
agrego el módulo emb
de muebles empotrados del intérprete embebido. También me gustaría importarlo automáticamente, para que los usuarios no tengan que emitir la declaración import emb
en sus scripts provistos a mi intérprete incorporado. Estoy intentando dos formas de importar, en las líneas (1) y (2).
El (1) obras y el módulo emb
se pueden encontrar sin importar explícita en la simple prueba en línea (3). Sin embargo, si comento hacia fuera de la línea de (1) y elimine la línea (2) importar con C API de Python 3 llamada, entonces la línea (3) produce error:
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'emb' is not defined
Me gustaría entender cuál es la diferencia entre las dos maneras de importar. ¿Importan módulos en diferentes namespaces/scopes?
El Python 3 documentación me llevó a lo largo de este camino:
- PyImport_ImportModule se describe mejor haciendo referencia a la función integrada en función de Python
__import__()
__import__()
es invocada por la declaración de importación.
Tal vez he cometido un error asumir PyImport_ImportModule
es uno-a-uno equivalente y que debería usar PyImport_ImportModuleEx con correcta (que es exactamente?) Globales y locales, así que mis tierras 'emb' en espacio de nombres global de mi intérprete embebido .
+1 ¡Trabajos! Veo dónde estaba mi malentendido. Si no se ha probado el código, solo "emb" necesita ser envuelto con PyUnicode_FromString ("emb"). También noté que hay un atajo para obtener __main__: PyObject * main_module = PyImport_AddModule ("__ main__"); – mloskot
Editado, gracias. Usé 'PyObject_SetAttrString' en lugar de' PyUnicode_FromString' (más corto, menos preocupante sobre la administración de referencias). –
Creo que el valor de retorno de PyImport_AddModule es una referencia prestada, por lo que no debería estar decretándolo. –