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

如何用boost::python从C++暴露带可变参数的Python风格函数?

使用Boost.Python暴露含混合参数类型的C++函数

完全可以实现你要的函数原型,Boost.Python的raw_function支持通过指定强制位置参数数量,来拆分固定参数、可变位置参数和可变关键字参数。以下是具体实现方案:

一、暴露带固定参数+*args+**kwargs的函数

针对你给出的test_kwargs_bis(int i, py::tuple args, py::dict kwargs),只需在暴露时给raw_function传入第二个参数,指定强制位置参数的个数(这里是1),Boost.Python会自动将前1个参数解析为int i,剩余位置参数打包为args,关键字参数打包为kwargs。

C++实现代码

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

namespace py = boost::python;

py::object test_kwargs_bis(int i, py::tuple args, py::dict kwargs)
{
    std::cout << "固定参数i: " << i << std::endl;
    std::cout << "可变位置参数数量: " << py::len(args) << std::endl;
    for (int j = 0; j < py::len(args); ++j) {
        std::cout << "args[" << j << "]: " << py::extract<int>(args[j]) << std::endl;
    }
    std::cout << "可变关键字参数数量: " << py::len(kwargs) << std::endl;
    py::list keys = kwargs.keys();
    for (int j = 0; j < py::len(keys); ++j) {
        std::string key = py::extract<std::string>(keys[j]);
        int value = py::extract<int>(kwargs[key]);
        std::cout << key << ": " << value << std::endl;
    }
    return py::object();
}

BOOST_PYTHON_MODULE(MyModule)
{
    // 第二个参数1表示强制要求1个位置参数
    py::def("test_kwargs_bis", py::raw_function(&test_kwargs_bis, 1));
}

Python测试调用

import MyModule
# 调用示例:i=10,args=(20,30),kwargs={"x":1,"y":2}
MyModule.test_kwargs_bis(10, 20, 30, x=1, y=2)

二、模拟Python的def f(a,b,c=0,*args,**kwargs)

要实现含必填参数、可选参数、可变位置/关键字参数的完整原型,可结合raw_function的参数指定和默认参数处理:

C++实现代码

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

namespace py = boost::python;

py::object f(int a, int b, py::object c, py::tuple args, py::dict kwargs)
{
    // 处理可选参数c的默认值:若Python未传,c为None,设为0
    int c_val = c.is_none() ? 0 : py::extract<int>(c);
    
    std::cout << "必填参数a: " << a << std::endl;
    std::cout << "必填参数b: " << b << std::endl;
    std::cout << "可选参数c: " << c_val << std::endl;
    
    // 遍历可变位置参数
    std::cout << "可变位置参数: ";
    for (int j = 0; j < py::len(args); ++j) {
        std::cout << py::extract<int>(args[j]) << " ";
    }
    std::cout << std::endl;
    
    // 遍历可变关键字参数
    std::cout << "可变关键字参数: ";
    py::list keys = kwargs.keys();
    for (int j = 0; j < py::len(keys); ++j) {
        std::string key = py::extract<std::string>(keys[j]);
        int value = py::extract<int>(kwargs[key]);
        std::cout << key << "=" << value << " ";
    }
    std::cout << std::endl;
    
    return py::object();
}

BOOST_PYTHON_MODULE(MyModule)
{
    // 2表示强制2个必填位置参数(a,b),通过py::arg给c设置默认值None
    py::def("f", py::raw_function(&f, 2), 
            (py::arg("a"), py::arg("b"), py::arg("c")=py::object()));
}

Python测试调用

import MyModule
# 不传c,使用默认值0
MyModule.f(1, 2, 4, 5, name="test", value=100)
# 传入c=30
MyModule.f(10, 20, 30, 40, 50, foo=1, bar=2)

核心要点

  • raw_function(func, n)中的n是必须传入的位置参数数量,Boost.Python会自动拆分前n个参数为C++函数的固定参数,剩余位置参数打包为tuple,关键字参数打包为dict。
  • 可选参数通过py::arg设置默认值为py::object()(对应Python的None),在C++函数内判断并赋予业务默认值即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:35:21