Ecco esempio canonico di un programma extending embedded Python 3.x in C/C++:Do PyImport_ImportModulo e importazione vengono caricati in spazi dei nomi diversi?
#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;
}
aggiungo il modulo emb
a built-in dell'interprete incorporato. Vorrei anche importarlo automaticamente, in modo che gli utenti non debbano rilasciare la dichiarazione import emb
negli script forniti all'interprete incorporato. Sto provando due modi di importazione, nelle righe (1) e (2).
Il (1) opere e il modulo emb
possono essere trovati senza importazione esplicito nel semplice test in linea (3). Tuttavia, se commento fuori linea (1) e rimuovere la linea (2) importare con C API di Python 3 chiamata, poi la linea (3) produce errore:
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'emb' is not defined
Mi piacerebbe capire qual è la differenza qui tra i due modi di importare. Importano il modulo in diversi namespaces/scopes?
Il Python 3 documentazione mi ha portato in questo cammino:
- PyImport_ImportModule è meglio descritta facendo riferimento alla funzione
__import__()
__import__()
funzione built-in Python viene invocato dalla dichiarazione di importazione.
Forse ho commesso un errore assumendo PyImport_ImportModule
è uno-a-uno equivalente e dovrebbe usare PyImport_ImportModuleEx con la corretta (che esattamente?) Globali e locali, così le mie terre 'emb' nel namespace globale del mio interprete incorporato .
+1 Opere! Vedo dov'era il mio fraintendimento. Re codice non testato, solo "emb" deve essere avvolto con PyUnicode_FromString ("emb"). Ho anche notato che c'è un collegamento per ottenere __main__: PyObject * main_module = PyImport_AddModule ("__ main__"); – mloskot
Modificato, grazie. Ho usato 'PyObject_SetAttrString' piuttosto che' PyUnicode_FromString' (più corto, meno preoccupante di gestire i riferimenti). –
Penso che il valore restituito da PyImport_AddModule sia un riferimento preso a prestito, quindi non dovresti decriverlo. –