2011-11-03 9 views
5

は、C/C++でプログラムextending embedded Python 3.xの標準的な例である:PyImport_ImportModuleとimport文を異なる名前空間に読み込みますか?ここ

#include <Python.h> 
//// Definition of 'emb' Python module //////////////////// 
static PyObject* emb_foo(PyObject *self, PyObject *args) 
{ 
    char const* n = "I am foo"; 
    return Py_BuildValue("s", n); 
} 
static PyMethodDef EmbMethods[] = { 
    {"foo", emb_foo, METH_VARARGS, "Returns foo"}, 
    {NULL, NULL, 0, NULL} 
}; 
static PyModuleDef EmbModule = { 
    PyModuleDef_HEAD_INIT, "emb", NULL, -1, EmbMethods, 
    NULL, NULL, NULL, NULL 
}; 
static PyObject* PyInit_emb(void) 
{ 
    return PyModule_Create(&EmbModule); 
} 
//// Embedded Python with 'emb' loaded //////////////////// 
int main() 
{ 
    PyImport_AppendInittab("emb", &PyInit_emb); 
    Py_Initialize(); 

    PyRun_SimpleString("import emb\n");  // (1) 
    //PyImport_ImportModule("emb");   // (2) 

    PyRun_SimpleString("print(emb.foo())\n"); // (3) 

    Py_Finalize(); 
    return 0; 
} 

Iは、埋め込みインタプリタのビルトインにembモジュールを追加します。 私はそれを自動的にインポートしたいので、ユーザは埋め込みインタープリタに提供されたスクリプトにimport embの文を発行する必要はありません。 私は2つのインポート方法を試しています。(1)(2)です。

(1)作品とembモジュールは、ライン(3)で簡単なテストでは、明示的なインポートすることなく求めることができます。私は、Python 3コールのCのAPIをインポートする(2)を(1)行をコメントアウトし、ラインのコメントを外し場合は、その行は(3)はエラーを生成します。

Traceback (most recent call last): 
    File "<string>", line 1, in <module> 
NameError: name 'emb' is not defined 

私は、輸入の2つの方法の違いは何かを理解したいと思います。 モジュールを異なるnamespaces/scopesにインポートしていますか?

ザ・Pythonの3のドキュメントは、このパスに沿って私を導い:

  1. PyImport_ImportModuleが最高のimport文で呼び出される組み込みのPython関数__import__()
  2. __import__()機能を用いて説明します。

おそらく、私は、1対1と同等であると私は私の組み込みインタプリタのグローバル名前空間に正しい(正確に?)グローバルと地元の人なので、私の「EMB」の土地でPyImport_ImportModuleExを使用する必要がありますPyImport_ImportModuleを想定してミスを犯しました。

答えて

7

__import__は、モジュールを名前空間にまったく入れませんが、代わりにモジュールを返します。 import__import__を呼び出し、結果を変数に格納します。

spam = __import__('spam', globals(), locals(), [], 0) 

は、C APIで同じ効果を得るには、あなたがグローバルembに割り当てる必要があります。 docsimport spamがに似た何かをすることを言います。つまり、__main__モジュールのemb属性を設定します。

PyObject* emb_module = PyImport_ImportModule("emb"); 
PyObject* main_module = PyImport_AddModule("__main__"); 
PyObject_SetAttrString(main_module, "emb", emb_module); 
Py_XDECREF(emb_module); 
/* (main_module is a borrowed reference) */ 
+0

+1 Works!私は私の誤解がどこであったかを見ます。テストされていないコードでは、単に "emb"をPyUnicode_FromString( "emb")でラップする必要があります。私はまた、__main__を取得するためのショートカットがあることに気付きました:PyObject * main_module = PyImport_AddModule( "__ main__"); – mloskot

+1

編集ありがとうございます。 'PyUnicode_FromString'ではなく' PyObject_SetAttrString'を使用しました。 –

+0

私はPyImport_AddModuleからの戻り値が借用された参照だと思うので、それをdecref'ingするべきではありません。 –

関連する問題