Cómo importar un archivo por su ruta completa usando la API de C?
-
22-09-2019 - |
Pregunta
* PyObject PyImport_ImportModule (const char * nombre)
Como especificar una ruta de acceso completa en lugar y un nombre de módulo?
Al igual que PyImport_SomeFunction(const char *path_to_script, const char *name)
Gracias, Elias
Solución 4
Finalmente, terminé usando el módulo de load_source imp:
s.sprintf(
"import imp\n"
"imp.load_source('%s', r'%s')", modname, script_path);
PyRun_SimpleString(s.c_str());
creo que es la solución más factible. Otras sugerencias son bienvenidos.
Otros consejos
Otra solución para los casos en que todos los archivos * .py se encuentran en un directorio:
PySys_SetPath("path/with/python/files");
PyObject *pModule = PyImport_ImportModule("filename_without_extension");
No puedo darle una respuesta completa, pero creo que puedo darle un lugar para empezar. Python proporciona una llamada imp
módulo integrado que proporciona acceso a los componentes internos de importación. Incluye un load_module () la función que le permite pasar de un camino. Esto se implementa en Python / import.c ; sólo la búsqueda de imp_load_module
.
Como se señaló, el uso de la solución anterior por AlexP, no se puede importar cualquier módulo fuera del directorio especificado. Sin embargo, en lugar de el ajuste de la ruta de acceso, puede añadir un camino, que se va a buscar para los módulos. Esto se puede hacer añadiendo ese camino a sys.path . Por desgracia, la API de C no expone una función que es capaz de hacerlo directamente. En su lugar puede preguntarse Python para hacerlo, utilizando
PyRun_SimpleString( "import sys\nsys.path.append(\"<insert folder path>\")\n" );
o cualquier equivalente como: (advertencia: no probado)
PyObject* sys = PyImport_ImportModule( "sys" );
PyObject* sys_path = PyObject_GetAttrString( sys, "path" );
PyObject* folder_path = PyUnicode_FromString( "<insert folder path>" );
PyList_Append( sys_path, folder_path );
Ahora usted puede importar cualquier archivo utilizando el <insert folder path>/<file>.py
habitual
PyObject* mymodule = PyImport_ImportModule( "<file>" );
Para hacer referencia al directorio actual, sólo tiene que utilizar "."
como la ruta de la carpeta.
no dude a través de la llamada imp
módulo para llevar a cabo los trabajos de importación, por lo que no hay razón para que no se debe hacerlo usted mismo.
Aquí hay una manera de hacerlo en C ++, donde modulePath
y moduleName
son variables independientes debido a la pereza:
PyObject* loadModule(const char* modulePath, const char* moduleName)
{
auto modules = PyImport_GetModuleDict();
auto impModule = PyDict_GetItemString(modules, "imp");
if (impModule)
{
// GetItemString returns a borrowed reference, but ImportModule
// returns a new reference, so INCREF here to even it out
Py_INCREF(impModule);
}
else
{
impModule = PyImport_ImportModule("imp");
if (!impModule)
{
// we've tried hard enough, bail out
PyErr_Print();
return nullptr;
}
}
// The Python API asks for non-const char pointers :(
char methodName[] = "load_source";
char args[] = "ss";
auto module = PyObject_CallMethod(impModule, methodName, args, moduleName, modulePath);
Py_XDECREF(impModule);
Py_XDECREF(modulePath);
return module;
}
Me escribió esta basado en uno de mis proyectos Python módulo del cargador de , que utiliza la administración refcount más elegante, y no he probado éste, por lo que su uso bajo su propio riesgo.
I verificó que la alternativa de stesim funciona.
No importa lo que se utiliza la solución, es importante mencionar que en las ventanas que es importante contar con la ruta completa con barras en lugar de barras invertidas.
path = "C:\\path\\to\\module\\module.py" // wrong
path = "C:/path/to/module/module.py" // correct
En algunas otras preguntas y respuestas (como de Windows en Python ) se afirma, que la primera variante debería funcionar también. No pude conseguir que funcione de esa manera cualquier método que he intentado.