C APIを使用して、完全なパスでファイルをインポートする方法?

StackOverflow https://stackoverflow.com/questions/1796925

  •  22-09-2019
  •  | 
  •  

質問

PyObject * PyImport_ImportModule(のconstのchar *名)

モジュール名を代わりに完全なファイルパスを指定してするには?

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

のように

おかげで、 エリアス

役に立ちましたか?

解決 4

は結局、私はIMPモジュールからload_sourceを使用して終了しました

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

私はそれが最も実現可能な解決策だと思います。他の提案は歓迎されます。

他のヒント

すべての*の.pyファイルが一つのディレクトリにある場合のための別の解決策ます:

PySys_SetPath("path/with/python/files");
PyObject *pModule = PyImport_ImportModule("filename_without_extension");
私はあなたに完全な答えを与えることはできませんが、私はあなたを開始する場所を与えることができると思います。 Pythonは、インポートの内部へのアクセスを提供する組み込みのモジュールと呼ばれるimpを提供します。それはあなたがパスに渡すことができます関数load_moduleを()が含まれています。これはのPython / import.cに実装されています;ただimp_load_moduleを探します。

としては、あなたが外に指定したディレクトリのすべてのモジュールをインポートすることはできません、AlexPによって上記の溶液を使用して、指摘しました。しかし、代わりにのパスを設定するには、のモジュールで検索するのパスを追加することができます。これはのsys.pathするにそのパスを追加することで行うことができます。残念ながら、C APIは、直接それを行うことが可能である機能を公開しません。代わりに、あなたは、Python自体が使用して、それを行うように依頼することができます。

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

などの任意の同等:の(警告:未試験)

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

今、あなたは、通常の

を使用して任意のファイル<insert folder path>/<file>.pyをインポートすることができます
PyObject* mymodule = PyImport_ImportModule( "<file>" );

カレントディレクトリを参照するには、単にフォルダパスとして"."を使用します。

CPythonのを通じて呼び出しにを躊躇しないだろうimpモジュールインポートジョブを実行するので、あなたはそれを自分でやるべきではないという理由はありません。

ここでmodulePathmoduleNameが原因怠惰の別々の変数であるC ++、でそれを行うための一つの方法です

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

私は私のプロジェクトの 1に基づいて本を書きましたご自身の責任で使用して、手の込んだ参照カウントの管理を使用し、私はこの1つを試していないのPythonモジュールローダーに、。

私は stesim の作品の代替ことを確認します。

使用されている解決策はありません問題は、それがWindows上で、スラッシュの代わりにバックスラッシュとの完全なパスを持っていることが重要であることを言及することは重要である。

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

(Pythonのの中 Windowsのパスのような)いくつかの他の質問と回答では、記載されています第一の変形は、あまりにも動作する必要があること。私はそれが私が試したどんな方法でそのように動作するように得ることができませんでした。

scroll top