Boost python,用命名空间调用函数对象

时间:2013-05-10 16:05:08

标签: boost-python python-embedding

我使用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中。

谢谢。

1 个答案:

答案 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++
相关问题