我使用boost python在我的C ++应用程序中嵌入python。
我希望能够调用boost python函数对象,并将全局名称空间与该函数调用相关联。具体而言,简化的相关代码是:
bp::object main = bp::import("__main__");
bp::object main_namespace = main.attr("__dict__");
//Put the function name runPyProg in the main_namespace
bp::object PyProg = exec(
"import cStringIO\n"
"import sys\n"
"sys.stderr = cStringIO.StringIO()\n"
"def runPyProg(exp):\n"
" print exp\n"
" exec(exp)\n"
" return\n"
"\n",main_namespace);
//Now call the python function runPyProg with an argument
bp::object py_fn = main.attr("runPyProg");
py_fn(expStr)
我知道当我使用boost python exec()函数时,我可以发送全局命名空间,如上所示。我的问题是当我调用py_fn时如何将main_namespace与python函数关联起来?我的最终目标是将runPyProg中的局部变量放在main_namespace中。
谢谢。
答案 0 :(得分:3)
如果我正确理解了这个问题,那么它应该像指定exec
将执行的上下文一样简单。函数或方法可以通过globals()
访问定义它的命名空间。因此,从globals()
内调用runPyProg()
将返回与main_namespace
相当的Python。另外,exec
有两个可选参数:
globals()
的字典。如果省略第二个参数,那么它也用于locals()
。locals()
的字典。 exec
内发生的变量应用于locals()
。因此,改变:
exec exp
到
exec exp in globals()
它应该提供所需的行为,其中exp
可以与main_namespace
中的全局变量进行交互。
这是一个基本的例子:
#include <boost/python.hpp>
int main()
{
Py_Initialize();
namespace python = boost::python;
python::object main = python::import("__main__");
python::object main_namespace = main.attr("__dict__");
//Put the function name runPyProg in the main_namespace
python::exec(
"def runPyProg(exp):\n"
" print exp\n"
" exec exp in globals()\n"
" return\n"
"\n", main_namespace);
// Now call the python function runPyProg with an argument
python::object runPyProg = main.attr("runPyProg");
// Set x in python and access from C++.
runPyProg("x = 42");
std::cout << python::extract<int>(main.attr("x")) << std::endl;
// Set y from C++ and access within python.
main.attr("y") = 100;
runPyProg("print y");
// Access and modify x in python, then access from C++.
runPyProg("x += y");
std::cout << python::extract<int>(main.attr("x")) << std::endl;
}
评论输出:
x = 42 // set from python
42 // print from C++
// y set to 100 from C++
print y // print y from python
100 //
x += y // access and modify from python
142 // print x from C++