我只是有一个功能对象:
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
答案 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 = ×_two;
int times_two_wrap(int x) { return func(x); }
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::def("times_two", ×_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 = ×_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
分配新值来在运行时更改底层实现。