2011-11-03 13 views
5

यहाँ सी/सी में एक कार्यक्रम extending embedded Python 3.x के विहित उदाहरण है ++:क्या PyImport_ImportModule और आयात स्टेटमेंट अलग नामस्थान में लोड करें?

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

मैं एम्बेडेड दुभाषिये की निर्मित-इन करने के लिए emb मॉड्यूल जोड़ें। मैं इसे स्वचालित रूप से आयात करना भी चाहूंगा, इसलिए उपयोगकर्ताओं को मेरे एम्बेडेड दुभाषिया को दी गई अपनी स्क्रिप्ट में import emb कथन जारी करने की आवश्यकता नहीं है। मैं आयात करने के दो तरीकों की कोशिश कर रहा हूं, (1) और (2) में।

(1) काम करता है और emb मॉड्यूल लाइन (3) में साधारण परीक्षण में स्पष्ट आयात के बिना पाया जा सकता है। हालांकि, अगर मैं लाइन (1) बाहर टिप्पणी और लाइन uncomment (2) अजगर 3 कॉल की सी एपीआई के साथ आयात करने के लिए है, तो लाइन (3) पैदा करता है त्रुटि:

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

मैं समझना चाहता हूं कि आयात के दो शिष्टाचार के बीच क्या अंतर है। क्या वे विभिन्न namespaces/scopes में मॉड्यूल आयात करते हैं?

अजगर 3 प्रलेखन मुझे इस मार्ग के किनारे का नेतृत्व किया:

  1. PyImport_ImportModule सर्वश्रेष्ठ अंतर्निहित अजगर समारोह __import__()
  2. __import__() समारोह की चर्चा करते हुए आयात बयान से शुरू हो जाती है द्वारा वर्णित है।

शायद मैं एक गलती मानते हुए बनाया PyImport_ImportModule एक-से-एक बराबर है और मैं सही साथ PyImport_ImportModuleEx का उपयोग करना चाहिए (जो वास्तव में?) वैश्विक और स्थानीय लोगों, इसलिए मेरे 'emb' मेरे एम्बेडेड दुभाषिया के वैश्विक नाम स्थान में भूमि ।

उत्तर

7

__import__ मॉड्यूल को किसी भी नामस्थान में बिल्कुल नहीं रखता है, लेकिन इसके बजाय इसे वापस करता है। import__import__ पर कॉल करता है, साथ ही यह परिणाम को एक चर में संग्रहीत करता है। docs का कहना है कि import spam को कुछ ऐसा ही:

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

सी एपीआई में एक ही प्रभाव पाने के लिए आपको emb वैश्विक को सौंपने होंगे। दूसरे शब्दों में, __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 काम करता है! मैं देखता हूं कि मेरी गलतफहमी कहां थी। पुनः अवांछित कोड, बस "emb" को PyUnicode_FromString ("emb") के साथ लपेटने की आवश्यकता है। मैंने यह भी देखा है कि __main__ प्राप्त करने के लिए शॉर्टकट है: PyObject * main_module = PyImport_AddModule ("__ main__"); – mloskot

+1

संपादित, धन्यवाद। मैंने 'PyUnicode_FromString' के बजाय' PyObject_SetAttrString' का उपयोग किया (संदर्भ, संदर्भों के प्रबंधन के बारे में कम चिंताजनक)। –

+0

मुझे लगता है कि PyImport_AddModule से वापसी मूल्य एक उधार संदर्भ है, इसलिए आपको इसे कम नहीं करना चाहिए। –

संबंधित मुद्दे