変数を返す
数値型を返す
def test_ret_int():
print "---- Return int ----"
code = """
return_val = 1;
"""
ret = weave.inline(code)
print "ret:", ret
Cの中でint型作成して返すサンプルです。Cのコードから値を返すときには、決してreturn文を使わないでください。weave内では、codeに書かれたコードに到達する前にreturn_valというSCXXのpy::objectが宣言されています。(生成されたcppファイルを見るとわかります。)return_valに代入された変数はweave.inlineメソッドの戻り値として受け取ることができます。APIを見るとわかりますが、py::objectのCの数値型や文字列型を代入すると、自動的にPythonのオブジェクトに変換してくれます。結果は次のようになります。
---- Return int ----
ret: 1
タプルなどを返す
def test_ret_tuple():
print "---- Return tuple ----"
code = """
if(scxxFlag) {
// scxx
py::tuple ret(2);
py::object tmp(1); ret.set_item(0, tmp);
tmp = 3.5; ret.set_item(1, tmp);
return_val = ret;
} else {
// Python C API is more reasnable.
return_val = Py_BuildValue("id", 1, 3.5);
}
"""
scxxFlag = 1
ret = weave.inline(code, ["scxxFlag", ])
print "ret (scxx):", ret
scxxFlag = 0
ret = weave.inline(code, ["scxxFlag", ])
print "ret (Py/C API):", ret
return_valはpy::object型なので、SCXXのpy::tuple, py::dictなどを代入することも可能ですし、Python/C APIのPyObject*を渡すこともできます。ここでは、if文のscxxFlagが1の場合はSCXXでtupleを、0の場合はPython/C APIでtupleを作成しています。(boolの受け渡しはサポートしていないっぽいので、scxxFlagをbool型にしませんでした。)
出力は以下。
---- Return tuple ----
ret (scxx): (1, 3.5)
ret (Py/C API): (1, 3.5)
両方とも同じ結果になっていますね。
Python/C APIの
Py_BuildValue
はとても便利なので使った方が良いと思います。フォーマットのiはint、dはdouble, sは文字列(char*), OはPyObject*を意味します。
listもdictも簡単に生成できるので試してみてください。
return_val = Py_BuildValue("[i,d]", 1, 3.5);// List
return_val = Py_BuildValue("{s:i,s:[d,s]}", "abc", 1, "def", 3.5, "Hoge"); // Dict
前回の例とあわせて、これで値の受け渡しができるようになりました。次回は、数値計算を利用している方向けに
NumpyのArrayを利用した例を見ていきます。
0 件のコメント:
コメントを投稿