Frage

PyObject * PyImport_ImportModule (const char * name)

Wie man einen vollständigen Dateipfad angeben, statt und einen Modulnamen?

Wie PyImport_SomeFunction(const char *path_to_script, const char *name)

Danke, Elias

War es hilfreich?

Lösung 4

Schließlich landete ich mit dem load_source von imp-Modul:

s.sprintf( 
  "import imp\n" 
  "imp.load_source('%s', r'%s')", modname, script_path); 
PyRun_SimpleString(s.c_str()); 

Ich denke, es ist die praktikabelste Lösung. Andere Vorschläge sind willkommen.

Andere Tipps

Eine andere Lösung für die Fälle, wenn alle * .py-Datei in einem Verzeichnis sind:

PySys_SetPath("path/with/python/files");
PyObject *pModule = PyImport_ImportModule("filename_without_extension");

Ich kann Ihnen keine vollständige Antwort geben, aber ich glaube, ich kann Ihnen einen Ort zu starten. Python bietet ein eingebautes Modul namens imp die Import-Interna Zugang zu bietet. Es enthält eine Funktion load_module (), die Sie in einem Pfad passieren lässt. Dies wird implementiert in Python / import.c ; suchen Sie einfach nach imp_load_module.

Wie bereits ausgeführt, die obige Lösung von AlexP verwenden, können Sie keine Module außerhalb des angegebenen Verzeichnisses importieren. Doch anstelle von Einstellung den Pfad, können Sie in ein Pfad, der für die Module gesucht werden soll. Dies kann durch Anhänge von diesem Pfad getan werden, um sys.path . Leider aussetzen der C-API keine Funktion in der Lage ist, die direkt zu tun. Stattdessen können Sie fragen Python selbst, es zu tun, mit

PyRun_SimpleString( "import sys\nsys.path.append(\"<insert folder path>\")\n" );

oder ein äquivalente wie: (Achtung: nicht getestet)

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 );

Jetzt können Sie eine beliebige Datei <insert folder path>/<file>.py importieren die übliche

mit
PyObject* mymodule = PyImport_ImportModule( "<file>" );

Um in das aktuelle Verzeichnis beziehen, einfach "." als Ordnerpfad verwenden.

CPython wird nicht zögern Anruf durch die imp Modul Importaufträge ausführen, so gibt es keinen Grund, dass Sie sollten es selbst nicht tun.

Hier ist eine Möglichkeit, es in C ++ zu tun, wo modulePath und moduleName sind separate Variablen wegen Faulheit:

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;
}

Ich schrieb dies basierend auf einem meiner Projekte Python-Modul loader , die schickere refcount Management nutzt, und ich habe nicht dieses versucht, so Verwendung erfolgt auf eigene Gefahr.

ich festgestellt, dass die Alternative von stesim funktioniert.

Unabhängig davon, welche Lösung verwendet wird, ist es wichtig, an den Fenstern zu erwähnen, dass es wichtig ist, mit Schrägstrichen statt Schrägstrichen den vollständigen Pfad zu haben.

path = "C:\\path\\to\\module\\module.py" // wrong
path = "C:/path/to/module/module.py"     // correct

In einigen anderen Fragen und Antworten (wie Windows-Pfad in Python ) wird angegeben, dass die erste Variante sollte auch funktionieren. Ich konnte es nicht, so zu arbeiten, was Methode, die ich versuchte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top