pybind11 でキーワード引数 (kwargs) を指定するには、pybind11::arg
を使います。
sample.cpp
#include <pybind11/embed.h>
#include <pybind11/pybind11.h>
namespace py = pybind11;
int main()
{
// python インタプリタを起動する
py::scoped_interpreter interpreter;
// numpy の各種オブジェクトを取得する
py::module numpy = pybind11::module::import("numpy");
py::object zeros = numpy.attr("zeros");
py::object float32 = numpy.attr("float32");
py::object int32 = numpy.attr("int32");
// numpy.ndarray を作る
py::object f32_array = zeros(10, py::arg("dtype") = float32);
py::object i32_array = zeros(10, py::arg("dtype") = int32);
// 配列の文字列表現を標準出力に書き出す
py::print(py::repr(f32_array));
py::print(py::repr(i32_array));
return 0;
}
$ # M1 Mac (Monterey) + Python 3.8.9 + pybind11 2.9.2 (Homebrew)
$ clang sample.cpp -std=c++20 -lc++ -lpython3.8 -rpath /Library/Developer/CommandLineTools/Library/Frameworks -I/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/Headers -I/opt/homebrew/Cellar/pybind11/2.9.2/include -L/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib -o sample
$ ./sample
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32)
また、可変長引数とキーワード引数を受け取る場合は pybind11::args
と pybind11::kwargs
を使います。
sample2.cpp
#include <pybind11/embed.h>
#include <pybind11/pybind11.h>
#include <utility>
namespace py = pybind11;
using std::pair;
void hello(py::args args, py::kwargs kwargs)
{
for (const py::handle& arg : args)
{
py::print(py::str(arg));
}
for (const pair<py::handle, py::handle>& kv : kwargs)
{
py::print(py::str(kv.first), "=", py::str(kv.second));
}
}
int main()
{
// python インタプリタを起動する
py::scoped_interpreter interpreter;
// main モジュール上に hello 関数を定義する
py::module main_module = py::module::import("__main__");
main_module.def("hello", &hello);
// python スクリプトから hello 関数を呼び出す
py::object scope = main_module.attr("__dict__");
py::exec("hello('hello', a = 1, b = 2, abc = 123)", scope);
return 0;
}
$ # M1 Mac (Monterey) + Python 3.8.9 + pybind11 2.9.2 (Homebrew)
$ clang sample2.cpp -std=c++20 -lc++ -lpython3.8 -rpath /Library/Developer/CommandLineTools/Library/Frameworks -I/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/Headers -I/opt/homebrew/Cellar/pybind11/2.9.2/include -L/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib -o sample2
$ ./sample2
hello
a = 1
b = 2
abc = 123
scoped_interpreter
の使い方と、必要なヘッダファイルの詳細は pybind11 で C++ から Python インタプリタを実行する を参照してください。
参考資料
-
pybind11 で C++ から Python インタプリタを実行する
https://yokaze.github.io/2018/02/11/ -
pybind11 で main モジュール上に関数を定義する
https://yokaze.github.io/2018/03/05/ -
Functions — pybind11 documentation
http://pybind11.readthedocs.io/en/stable/advanced/functions.html