小能豆

如何仅设置一个默认参数 pybind11

py

我有一个功能:

void my_functions(int a, int b = 42);

我只想使用默认参数来绑定它b

 m.def("my_functions", &my_functions, pb::arg("b") = 42); // just default for b

这不起作用,我得到:

/cache/venv/include/pybind11/pybind11.h:219:40: error: static assertion failed: The number of argument annotations does not match the number of function arguments
  219 |             expected_num_args<Extra...>(
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~^
  220 |                 sizeof...(Args), cast_in::args_pos >= 0, cast_in::has_kwargs),

正确的做法是什么?


阅读 21

收藏
2025-01-04

共1个答案

小能豆

要在 Pybind11 中只绑定带有默认参数 b 的函数 my_functions,需要明确指定函数签名的所有参数,并正确处理默认值。如果你希望为参数 b 指定默认值而忽略 a 的默认值,则需要在绑定时使用 py::arg 来显式地声明每个参数。

以下是正确的做法:

修改代码以支持默认参数绑定

在绑定函数时,您需要为所有参数显式地提供名称,即使某些参数没有默认值:

#include <pybind11/pybind11.h>

namespace py = pybind11;

void my_functions(int a, int b = 42) {
    // Function implementation
}

PYBIND11_MODULE(example, m) {
    m.def("my_functions", &my_functions, 
          py::arg("a"),            // Explicitly specify argument name for 'a'
          py::arg("b") = 42);      // Explicitly specify argument name and default value for 'b'
}

解释错误的原因

错误消息提示:

The number of argument annotations does not match the number of function arguments

这是因为 Pybind11 需要为函数中的每个参数提供一个对应的 py::arg,否则它无法正确地推断函数签名。

如果您只指定 py::arg("b") 而忽略了 a,Pybind11 会认为函数只接受一个参数,而这与实际的 C++ 函数签名不匹配。

如何正确绑定默认值

  1. 如果你只关心为 b 设置默认值,仍然需要为 a 指定一个名称,但不需要默认值:
    cpp m.def("my_functions", &my_functions, py::arg("a"), py::arg("b") = 42);

  2. 在 Python 调用时:
    python import example example.my_functions(10) # 'b' will default to 42 example.my_functions(10, 100) # Explicitly set 'b' to 100

结论

在 Pybind11 中绑定带有默认参数的函数时,必须为每个参数指定名称。如果某个参数有默认值,您可以通过 py::arg("name") = value 的形式来提供默认值,同时显式地声明所有参数名称。

2025-01-04