You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法将Python dict实例转换为C++类型,求问题排查

问题:Python字典转C++ std::map时类型转换失败

我尝试将Python的dict[str, object]传递到C中操作,希望在C中保留该对象,但运行时报错:Unable to cast Python instance of type <class 'dict'> to C++。

相关代码

C++代码

typedef std::map<std::string, py::object> dataMap;

void init_basicWindowMule(pybind11::module_ & m) {
    pybind11::class_<testObject, QObject> widgetClass(m, "basicWindow");
    widgetClass.def(pybind11::init<>());
    widgetClass.def("create", [](py::object obj) {
        manager = new testObject();
        manager->setData(obj.cast<dataMap>());
    });
}

Python调用代码

PyBindTest.basicWindow.create({"someStuff":testObject()})

问题原因与解决方法

  • 直接用obj.cast<dataMap>()无法让pybind11自动完成Python字典到std::map<std::string, py::object>的转换,尤其是当字典包含自定义C++对象实例时,这种隐式转换不被支持。
  • 正确做法是手动遍历Python字典,逐个处理键值对后存入C++的std::map,同时提前校验输入类型避免异常。

修改后的C++代码如下:

typedef std::map<std::string, py::object> dataMap;

void init_basicWindowMule(pybind11::module_ & m) {
    pybind11::class_<testObject, QObject> widgetClass(m, "basicWindow");
    widgetClass.def(pybind11::init<>());
    widgetClass.def("create", [](py::object obj) {
        // 校验输入是否为Python字典
        if (!py::isinstance<py::dict>(obj)) {
            throw py::type_error("Expected a Python dict");
        }
        py::dict py_dict = obj.cast<py::dict>();
        dataMap cpp_map;
        // 遍历字典转换键值对
        for (auto& item : py_dict) {
            std::string key = py::cast<std::string>(item.first);
            py::object value = item.second;
            cpp_map[key] = value;
        }
        manager = new testObject();
        manager->setData(cpp_map);
    });
}

说明

手动遍历转换能明确控制每个键值对的处理过程,py::object可以完整保留Python侧的对象引用(包括自定义的testObject实例),满足在C++中保留对象的需求,同时提前的类型校验能避免非法输入导致的异常。

内容的提问来源于stack exchange,提问作者Dariusz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 03:07:20