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

如何声明可接受任意Python可迭代对象的C++函数?

解决方案

1. 接受任意Python可迭代对象

直接把函数参数类型改成boost::python::object,借助Boost.Python的迭代器适配Python的迭代协议,所有实现了__iter__方法的对象(包括列表、元组、集合、生成器、自定义迭代类等)都能正常传入。

示例代码:

#include <boost/python.hpp>
#include <boost/python/iterator.hpp>

using namespace boost::python;

void myf(const object& iterable) {
    // 创建迭代器遍历可迭代对象
    iterator iter_begin(iterable), iter_end;
    for (; iter_begin != iter_end; ++iter_begin) {
        object elem = *iter_begin;
        // 根据需求处理元素,比如转为C++类型
        if (extract<int>(elem).check()) {
            int value = extract<int>(elem);
            // 这里写入你的业务逻辑,比如处理value
        } else {
            // 类型不匹配时抛出Python异常
            PyErr_SetString(PyExc_TypeError, "元素类型不符合要求");
            throw_error_already_set();
        }
    }
}

BOOST_PYTHON_MODULE(your_module) {
    def("myf", &myf);
}

2. 退而求其次接受任意集合(序列/集合类型)

如果只需要支持list、tuple、set这类集合类型,可以在函数内部先做类型检查。不过第一种方案已经覆盖了这些集合类型,更推荐直接用第一种。要是要严格限制为集合,可结合PySequence_Check或PySet_Check判断:

示例代码:

void myf(const object& collection) {
    // 检查是否是序列(list、tuple等)或集合
    if (!PySequence_Check(collection.ptr()) && !PySet_Check(collection.ptr())) {
        PyErr_SetString(PyExc_TypeError, "必须传入序列或集合类型");
        throw_error_already_set();
    }

    // 后续遍历逻辑同可迭代对象方案
    iterator iter_begin(collection), iter_end;
    for (; iter_begin != iter_end; ++iter_begin) {
        object elem = *iter_begin;
        // 处理元素...
    }
}

关键说明

  • 用boost::python::object做参数是最灵活的方式,能兼容所有Python对象,再通过迭代器或类型检查筛选目标对象。
  • 转换Python对象到C++类型时,用extract<T>的check()方法判断转换是否成功,避免运行时出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:57:17