Pybind11自定义类型转换器的默认参数绑定问题
问题与解决方案
问题场景
现有C++函数:
void my_functions(int a, some_type b);
尝试为参数b设置默认值并通过pybind11绑定到Python:
m.def("my_functions", &my_functions, pb::arg("a"), pb::arg("b") = function_that_returns_my_type()); // 只为b设置默认值
其中some_type在PYBIND11_NAMESPACE中声明了自动自定义类型转换器,代码可正常编译,但在Python中调用my_functions(5)时抛出错误:
TypeError: my_functions(): incompatible function arguments. The following argument types are supported: 1. (a: int, b: some_type = python_object_custom_casted)
解决方案
问题根源是pybind11无法自动将带自定义转换器的C++类型默认值转换为Python对象,需显式完成类型转换:
方案1:直接用py::cast转换默认值
修改绑定代码,将function_that_returns_my_type()的结果显式转换为Python对象:
m.def("my_functions", &my_functions, pb::arg("a"), pb::arg("b") = py::cast(function_that_returns_my_type()));
方案2:先转换为py::object再绑定
先将C++默认值转换为py::object类型,再作为默认参数传入:
some_type default_b = function_that_returns_my_type(); py::object py_default_b = py::cast(default_b); m.def("my_functions", &my_functions, pb::arg("a"), pb::arg("b") = py_default_b);
原理说明
当自定义类型转换器存在时,直接传入C++对象作为默认参数,pybind11无法自动完成到Python对象的转换,导致Python端无法识别该默认值的合法类型。通过显式调用py::cast完成转换后,pybind11能正确识别默认值的类型,允许Python调用时省略b参数。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

