如何从Python传递嵌套列表到接收boost::python::list的C++函数?
错误原因
你当前的报错是因为处理一维列表的逻辑默认会尝试将列表内所有元素直接转换为std::string,一维平列表的元素都是字符串类型,所以可以正常运行;当传入嵌套列表时,内层元素本身是Python list类型,Boost Python没有默认注册list转std::string的转换器,因此抛出类型错误。
实现方案
你不需要修改Python侧的调用逻辑,只需要在C++侧增加列表元素的类型判断逻辑,递归解析嵌套结构即可,示例代码如下:
#include <boost/python.hpp> #include <boost/python/list.hpp> #include <string> #include <iostream> #include <variant> #include <vector> // 定义可存储字符串/嵌套列表的异构C++类型 using NestedListElem = std::variant<std::string, std::vector<NestedListElem>>; using NestedList = std::vector<NestedListElem>; // 递归解析Python嵌套列表的辅助函数 NestedList parse_py_nested_list(const boost::python::list& py_list) { NestedList res; int list_len = boost::python::len(py_list); for (int i = 0; i < list_len; ++i) { boost::python::object elem = py_list[i]; // 先判断是否为字符串类型 boost::python::extract<std::string> str_extractor(elem); if (str_extractor.check()) { res.emplace_back(str_extractor()); continue; } // 再判断是否为列表类型,递归解析 boost::python::extract<boost::python::list> list_extractor(elem); if (list_extractor.check()) { res.emplace_back(parse_py_nested_list(list_extractor())); continue; } // 其他元素类型可按需扩展处理逻辑 throw std::runtime_error("Unsupported element type in input list"); } return res; } // 业务函数实现 int my_cpp_func(const boost::python::list& arg) { NestedList parsed_data = parse_py_nested_list(arg); // 此处填写你的业务逻辑,处理解析后的嵌套列表数据 return 0; } // Boost Python模块绑定 BOOST_PYTHON_MODULE(your_module_name) { boost::python::def("my_cpp_func", &my_cpp_func); }
注意事项
- 如果你使用的C版本不支持C17的
std::variant,可以替换为boost::variant实现相同的异构元素存储能力 - 如果需要支持整数、浮点数等其他元素类型,只需在辅助函数的类型判断分支中增加对应类型的
extract判断逻辑即可 - 示例中将参数改为
const boost::python::list&是更安全的写法,如果你需要在C++侧修改传入的Python列表,改回非const引用即可
内容的提问来源于stack exchange,提问作者newbie
相关产品推荐
相关产品推荐

