boost-python ではじめる大規模機械学習 (2) - データの受け渡し

あらすじ

boost-python を使用して、Python と C 言語両方を活用する方法を説明しています。
前記事では、C 言語で Hello world を出力する関数を作成し、これを Python から呼び出す方法を説明しました。
本記事では、ふたつの言語の間で簡単なデータを受け渡す方法について解説します。

プリミティブの受け渡しは簡単

渡したいデータが文字列や数値である場合は、何も気兼ねする必要がありません。

hello.cpp
#include <string>
#include <boost/python.hpp>
using namespace boost::python;

double increment(int x)
{
    return x + 1;
}

std::string add_txt(std::string x)
{
    return x + ".txt";
}

BOOST_PYTHON_MODULE(hello)
{
    def("increment", increment);
    def("add_txt", add_txt);
}
実行結果

実行時型チェックもあります。すばらしいです。

$ python
>>> import hello
>>> hello.increment(2)
3.0
>>> hello.add_txt('test')
'test.txt'
>>> hello.increment()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
    hello.increment()
did not match C++ signature:
    increment(int)
>>>

タプルの受け渡しも簡単

Python のタプルも簡単に扱うことができます。
extract 関数を使用して、Python オブジェクトを C 言語のプリミティブに変換します。

hello.cpp
#include <string>
#include <boost/python.hpp>
using namespace boost::python;

object export_tuple()
{
    return make_tuple(1, 2, 3);
}

void import_tuple(object tup)
{
    size_t num = len(tup);

    for (size_t i = 0; i < num; i++)
    {
        std::cout << (extract<double>(tup[i]) + 1) << std::endl;
    }
}

BOOST_PYTHON_MODULE(hello)
{
    def("export_tuple", export_tuple);
    def("import_tuple", import_tuple);
}
実行結果

C 言語側では、tup オブジェクトにインデックスでアクセスしているだけであり、引数がタプルであるとは書いていません。したがって、リスト型でも動作するコードになっています。
型安全とはどこへやらという感じです。Python らしい。

>>> import hello
>>> hello.export_tuple()
(1, 2, 3)
>>> hello.import_tuple((1, 2, 3))
2
3
4
>>> hello.import_tuple([1, 2, 3])
2
3
4
>>> 


次回からが本番です。続く...