Pybind11默认参数numpy数组或无

时间:2019-12-10 15:29:13

标签: python c++ numpy binding pybind11

我包装了一些C ++代码以从Python使用它。我想使用一个参数来调用C ++函数,该参数可以采用None值或与其他输入变量大小相同的numpy.array。这是示例:

import example

# Let I a numpy array containing a 2D or 3D image
M = I > 0
# Calling the C++ function with no mask
example.fit(I, k, mask=None)
# Calling the C++ function with mask as a Numpy array of the same size of I
example.fit(I, k, mask=M)

如何使用pybind11在C ++中进行编码?我具有以下功能签名和代码:

void fit(const py::array_t<float, py::array::c_style | py::array::forcecast> &input, 
         int k,
         const py::array_t<bool, py::array::c_style | py::array::forcecast> &mask)
{
    ...
}

PYBIND11_MODULE(example, m)
{
    m.def("fit", &fit,
        py::arg("input"),
        py::arg("k"),
        py::arg("mask") = nullptr // Don't know what to put here?
    );

非常感谢您!

1 个答案:

答案 0 :(得分:1)

使用C ++ 17的std::optional,下面的示例应该可以工作。对于早期版本的C ++,您可能需要向后移植optional.h并实现自己的optional_caster,类似于pybind11/stl.h中的版本。

说您想要此功能:

def add(a, b=None):
    # Assuming a, b are int.
    if b is None:
        return a
    else:
        return a + b

这是等效的C ++ pybind实现:

m.def("add",
    [](int a, std::optional<int> b) {
        if (!b.has_value()) {
            return a;
        } else {
            return a + b.value();
        }
    },
    py::arg("a"), py::arg("b") = py::none()
);

在python中,可以使用以下函数调用该函数:

add(1)
add(1, 2)
add(1, b=2)
add(1, b=None)

对于numpy数组,只需在示例中将std::optional<int>更改为std::optional<py:array>std::optional<py:array_t<your_custom_type>>

相关问题