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

如何在pybind11模块中正确检查Python对象的数据类型?

在pybind11中正确检查Python类型的方法

问题重现

你编写的pybind11模块代码如下:

PYBIND11_MODULE(testmodule, m)
{
    // Assume Value class has been exposed here

    m.def("processDict", [](py::str expr, py::dict valueDict) {
        std::map<std::string, Value> cppValueDict;
        for (auto item : d) {
            // Convert key to std::string
            std::string key = item.first.cast<std::string>();
            
            // Trying to check python value type and cast it to custom datum type
            if (pybind11::isinstance(item.second, pybind11::int_) {
                cppValueDict.insert({key, CustomDatum::createIntDatum(pybind11::cast<int>(item.second))});
            } else {
                cppValueDict.insert({key, CustomDatum::createStringDatum(pybind11::cast<std::string>(item.second))});
            }
        }
        process(expr, cppValueDict);
   });
}

当Python脚本传入dict_obj = {"a": 1, "b": "Hello"}调用processDict时,报错:Unable to cast Python instance of type <class 'int'> to C++ type 'std::string',说明int类型的判断未生效,代码走到else分支尝试强制转换int为string导致错误。

错误原因分析

  1. 循环变量错误:代码中遍历的是未定义的变量d,实际应遍历函数参数valueDict。
  2. isinstance用法错误:pybind11::isinstance(obj, type)形式的第二个参数需要传入Python类型对象实例,而pybind11::int_是类型模板,并非可直接传入的实例。
  3. 语法错误:if条件语句末尾缺少闭合括号,导致编译逻辑异常。

正确的类型检查方式

pybind11提供两种可靠的类型检查方案:

1. 模板参数形式(推荐用于基础类型)

使用pybind11::isinstance<T>(obj),其中T为pybind11封装的基础类型模板(如pybind11::int_、pybind11::str),这种方式编译期即可确定类型,效率更高:

// 检查是否为int类型
if (pybind11::isinstance<pybind11::int_>(item.second)) {
    // 处理int类型逻辑
}
// 检查是否为字符串类型
else if (pybind11::isinstance<pybind11::str>(item.second)) {
    // 处理字符串类型逻辑
}

2. 类型对象形式(适用于自定义类型/动态判断)

如果需要检查自定义Python类型,或动态获取类型对象进行判断,可使用pybind11::isinstance(obj, type_obj):

  • 基础类型可通过pybind11::int_()、pybind11::str()获取类型对象实例
  • 自定义类型可使用py::type::of<CustomType>()(需提前暴露该类型),或直接引用暴露时的类型变量

示例:

// 检查基础int类型
if (pybind11::isinstance(item.second, pybind11::int_())) {
    // 处理逻辑
}
// 检查自定义类型CustomType
if (pybind11::isinstance(item.second, py::type::of<CustomType>())) {
    // 处理自定义类型逻辑
}

修正后的完整代码

PYBIND11_MODULE(testmodule, m)
{
    // Assume Value class has been exposed here

    m.def("processDict", [](py::str expr, py::dict valueDict) {
        std::map<std::string, Value> cppValueDict;
        // 修正:遍历正确的函数参数valueDict
        for (auto item : valueDict) {
            std::string key = item.first.cast<std::string>();
            
            // 使用模板参数形式的isinstance做类型检查
            if (pybind11::isinstance<pybind11::int_>(item.second)) {
                cppValueDict.insert({key, CustomDatum::createIntDatum(pybind11::cast<int>(item.second))});
            } else if (pybind11::isinstance<pybind11::str>(item.second)) {
                cppValueDict.insert({key, CustomDatum::createStringDatum(pybind11::cast<std::string>(item.second))});
            } else {
                // 可选:添加未支持类型的错误抛出,避免后续转换崩溃
                throw pybind11::type_error("Unsupported value type");
            }
        }
        process(expr, cppValueDict);
   });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 14:15:28