如何在pybind11中仅为单个函数参数设置默认值?
我有如下C++函数:
void my_functions(int a, int b = 42);
希望在使用pybind11绑定该函数时,仅为参数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),
请问正确的实现方式是什么?
这个错误的核心原因是:pybind11要求参数注解的数量必须和函数的参数总数完全一致——哪怕你只需要给后面的参数设置默认值,前面的参数也得显式提供注解(可以不设置默认值)。
正确的实现有两种方式:
显式声明所有参数的注解
明确写出每个参数的注解,为b设置默认值:m.def("my_functions", &my_functions, pb::arg("a"), pb::arg("b") = 42);这种方式的好处是Python调用时可以用关键字参数(比如
my_functions(a=10, b=20)),可读性更强。使用空占位符简化写法
如果不需要给第一个参数指定名字,用空的pb::arg()占位即可:m.def("my_functions", &my_functions, pb::arg(), pb::arg("b") = 42);这种写法更简洁,同样能让pybind11匹配参数数量,同时为b保留默认值。
内容的提问来源于stack exchange,提问作者Ivan

