1

私は単に関数オブジェクトを持っています:

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
4

1 に答える 1

2

boost::python::def()ドキュメントには、null以外の関数またはメンバー関数ポインターが提供された場合にのみdocstringを提供できることが記載されています。1つの解決策は、関数オブジェクト呼び出しを関数でラップすることです。

#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にうまく転送されていないように見えます。代わりに、を使用してPython関数を作成してから、以下に示すboost::python::make_function()ように、下位レベルの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");
}

これにより、インタラクティブな使用法と同じ出力が生成されます。2つのアプローチの唯一の顕著な動作の違いは、最初の例では、に新しい値を割り当てることにより、実行時に基盤となる実装を変更できることfuncです。

于 2013-03-26T00:48:13.877 に答える