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

如何通过pybind11将C++类的std::vector引用以属性传入Python?

问题原因

你的绑定代码无法生效有两个核心问题:

  1. def_property 要求同时传入 getter 和 setter 两个参数,你仅提供了 getter;
  2. 默认情况下 pybind11 会拷贝 std::vector<int> 生成 Python list,无法实现 C++ 容器与 Python 对象的双向同步修改。

可行实现方式

方式一:给C++类添加setter成员函数

先修改C++类A,新增用于设置vector的成员函数:

class A {
public:
    std::vector<int>& v() { return m_v; }
    // 新增setter,用于替换整个vector
    void set_v(const std::vector<int>& new_v) { m_v = new_v; }
    // 可选:添加移动语义版本,提升赋值性能
    void set_v(std::vector<int>&& new_v) { m_v = std::move(new_v); }

private:
    std::vector<int> m_v;
};

再修改pybind11绑定代码,同时传入getter、setter,并指定返回值策略以支持双向同步:

pybind11::class_<A>(m, "A")
    .def(pybind11::init<>())
    .def_property("v",
        &A::v,
        &A::set_v,
        pybind11::return_value_policy::reference_internal
    );

方式二:不修改C++类,用lambda实现setter

如果不想改动C++代码,可以在绑定阶段用lambda表达式替代setter:

pybind11::class_<A>(m, "A")
    .def(pybind11::init<>())
    .def_property("v",
        [](A& a) -> std::vector<int>& { return a.v(); },
        [](A& a, const std::vector<int>& new_v) { a.v() = new_v; },
        pybind11::return_value_policy::reference_internal
    );

Python端使用效果

完成绑定后,你可以像操作普通Python列表一样使用该属性:

a = A()
# 赋值整个vector
a.v = [1, 2, 3]
# 读取vector内容
print(a.v)  # 输出 [1, 2, 3]
# 原地修改(如追加元素)
a.v.append(4)
print(a.v)  # 输出 [1, 2, 3, 4]

注意:return_value_policy::reference_internal 是关键,它确保Python端操作的是C++ vector的引用,所有修改会同步到C对象;如果省略该策略,Python得到的是vector的拷贝,修改不会影响C端的原始数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:28:31