使用docstring定义boost :: function(Boost :: Python)

时间:2013-03-25 21:25:29

标签: c++ boost-python docstring

我只是有一个功能对象:

boost::function<int(int)> func = /** ... **/;

并希望使用docstring将其公开给Python 但显而易见的是:

def("func", func, "Some boring documentation goes here.");

失败的~2500行有趣的消息。

有什么想法吗?


编辑:我做了其他测试:

def("func", func); // doesn't compile

def("func",
   make_function(
     func,
     default_call_policies(),
     vector<int,int>()
   )
); // compiles

def("func",
   make_function(
     func,
     default_call_policies(),
     vector<int,int>()
   ),
   "Some boring documentation goes here"
); // doesn't compile

1 个答案:

答案 0 :(得分:2)

boost::python::def()文档提到只有在提供非null函数或成员函数指针时才能提供docstring。一个solution是将函数对象调用包装在函数中:

#include <boost/function.hpp>
#include <boost/python.hpp>

int times_two(int x) { return x * 2; }

boost::function<int(int)> func = &times_two;

int times_two_wrap(int x) { return func(x); }

BOOST_PYTHON_MODULE(example)
{
  namespace python = boost::python;
  python::def("times_two", &times_two_wrap,
              "returns two times the supplied value");
}

交互式使用:

>>> import example
>>> assert(6 == example.times_two(3))
>>> print help(example.times_two)

times_two( (int)arg1) -> int :
    returns two times the supplied value

    C++ signature :
        int times_two(int)
>>>

Boost.Python有多个API层。最高层主要是文档化的,但它使用了文档较少的低层API。在这种特殊情况下,看起来更高级别的API很难转发到较低级别的API。可以使用boost::python::make_function()创建一个python函数,然后使用低级boost::python::objects::add_to_namespace()函数,如下面的demonstrated

#include <boost/function.hpp>
#include <boost/python.hpp>

int times_two(int x) { return x * 2; }

boost::function<int(int)> func = &times_two;

BOOST_PYTHON_MODULE(example)
{
   namespace python = boost::python;
   // Wrap the functor in a Python object.
   python::object py_func = python::make_function(
     func,
     python::default_call_policies(),
     boost::mpl::vector<int, int>());
   // Add the function directly to the namespace.
   python::objects::add_to_namespace(
     python::scope(), // current namespace,
     "times_two",     // function name,
     py_func,         // function,
     "returns two times the supplied value");
}

这会产生与交互用法相同的输出。两种方法之间唯一值得注意的行为差异在于,第一个示例允许通过为func分配新值来在运行时更改底层实现。