2013-11-04 50 views
0

我使用BoostPython將Python嵌入到我的C++項目中,但我不明白所有關於Python的東西,特別是命名空間系統。Boost Python - 全球和本地詞典

其實,我用這個代碼:

byte_code = Py_CompileString(filedata, filename, Py_file_input); 

// [...] 

PyObject* res = NULL; 

PyObject* main_module = PyImport_AddModule("__main__"); 
PyObject* global_dict = PyModule_GetDict(main_module); 
PyObject* local_dict = PyDict_New(); 
py::object local_namespace(py::handle<>(py::borrowed(local_dict))); 

// Set a user object (only for this execution) 
local_namespace["user_object"] = py::ptr(&MyObject); 

res = PyEval_EvalCode(byte_code, global_dict, local_dict); 

Py_XDECREF(res); 
Py_XDECREF(local_dict); 

但是當我執行一個Python腳本,如:

def testB(): 
    print("B") 

def testA(): 
    testB() # NameError: global name 'testB' is not defined 

testA() # Works 
testB() # Works 

好了,我可以用

res = PyEval_EvalCode(byte_code, global_dict, global_dict); 

,而不是

res = PyEval_EvalCode(byte_code, global_dict, local_dict); 

但我想保留任何新的功能定義global_dict(因爲當我將推出一個新的腳本,我不想從一個非常古老的執行以前的函數定義可以叫你!)

這是一個關於命名空間的問題,不是嗎?

回答

0

是的,這是一個名稱空間問題。你應該看看Python處理範圍的方式(特別是「self」關鍵字)。

總之,類成員變量和函數的前綴是「self」。以指定它們是當前對象範圍的成員。 「Self」與C++和C#中的「this」關鍵字大致相似。

+0

謝謝你的回答。我試過「self.testB()」,但它不起作用...(NameError:全局名稱'自我'沒有定義)我想這不是一個Python類。嗯,也許我必須刪除global_dict中的所有內容來清除它... – yoder

+0

...也許我找到了更好的解決方案!我使用「PyDict_Copy」來複制global_dict。然後我發送「PyEval_EvalCode(byte_code,copy_dict,copy_dict)」的副本。在此之後,我可以垃圾這個副本來保存真正的global_dict! – yoder

+0

我沒有想到只是增加了「自我」。上班。請做你的功課。如果您瞭解「自我」關鍵字的含義和意義,這將是有道理的。 儘管您的解決方案可能「有效」,但除非您瞭解與其他解決方案的不同之處,否則它幾乎不會更好。範圍解析是一個非常基本的Python概念,您應該在嘗試解決它之前瞭解它的工作原理。 不要氣餒,你的初始本能是正確的,這是一個命名空間問題。瞭解Python處理範圍和名稱空間的方式將比解決問題更好地解決您的問題。 – Matt