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アプリケーションにバンドルされているスクリプトから関数をインポートしたい場合、これは適切な解決策ですか?