2

C / C ++を使用したPythonの拡張に関するPythonのドキュメントを調べていたところ、非常に興味深いシナリオが見つかりました。test_script.py作業ディレクトリに次のような簡単なPythonスクリプトがあると考えてください。

import time
def My_Python_Func():
    print "My_Python_Func() Called: " + str(time.time())

同じディレクトリに、というファイルがあります。このファイルanother_test_script.pyには次のものがあります。

import test_script
test_script.My_Python_Func()

と呼ばれると、これは正常に機能しpython ./another_test_script.pyます。今、私は次のようにPythonライブラリにリンクされたC環境から上記の関数を呼び出そうとしています。

#include <stdio.h>
#include <Python.h>

PyObject *pName, *pModule, *pDict, *pFunc, *pVal;

int main()
{
    const char* script_name = "test_script";
    const char* func_name   = "My_Python_Func";

    Py_Initialize();

    pName = PyString_FromString(script_name);

    PyRun_SimpleString("import os");
    PyRun_SimpleString("import sys");
    /* * * * IF I COMMENT THE FOLLOWING LINE OUT, pModule IS ALWAYS SET TO NULL * * * */
    PyRun_SimpleString("sys.path.insert(0, os.getcwd())");
    pModule = PyImport_Import(pName);

    Py_DECREF(pName);
    if (pModule != NULL)
    {
        pFunc = PyObject_GetAttrString(pModule, func_name);
    }
    pDict = PyModule_GetDict(pModule);
    pFunc = PyDict_GetItemString(pDict, func_name);
    if (PyCallable_Check(pFunc))
    {
        PyObject_CallObject(pFunc, NULL);
        Py_DECREF(pModule);
        Py_DECREF(pName);
    }
    else
    {
        PyErr_Print();
    }
    Py_Finalize();
    return 0;
}

上記のCプログラムのコメントに記載されているように、を含む行をコメントアウトするPyRun_SimpleString("sys.path.insert(0, os.getcwd())")と、呼び出しはPyImport_Import失敗します(returning NULL)。さらに、呼び出しPyRun_SimpleString("import test_script")は同じように動作するように見えます。

sys.path同じ作業ディレクトリ内の別のPythonスクリプトからインポートするだけなのに、現在の作業ディレクトリをPythonの文字列リストに手動で追加する必要があるのはなぜですか?さらに、Pythonが最初に現在の作業ディレクトリを検索しないのはなぜですか(os.getcwd()正しいパスを返すため)?Cアプリケーションにバンドルされているスクリプトから関数をインポートしたい場合、これは適切な解決策ですか?

4

1 に答える 1

4

スクリプトディレクトリをに追加することは、実行可能ファイルsys.pathの特性です。python組み込みアプリケーションでこれを行うことが常に適切であるとは限らないため、インタプリタが初期化されるときにデフォルトで実行されるわけではありません。

于 2012-10-25T22:06:39.520 に答える