用docstring (boost:: Python)定义boost::函数

Define a boost::function with a docstring (Boost::Python)

本文关键字:boost 定义 函数 docstring Python      更新时间:2023-10-16

我只是有一个函数对象:

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

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

#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)
>>>

提振。Python有多个API层。最高层大部分都有文档,但它使用文档较少的低级API。在这种特殊情况下,看起来似乎高级API转发给低级API的效果很差。可以使用boost::python::make_function()创建python函数,然后使用较低级别的boost::python::objects::add_to_namespace()函数,如下所示:

#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分配一个新值来更改底层实现。