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

如何通过pybind11将std::map导出为可点访问的对象而非字典?

如何在pybind11中让std::map支持Python点语法访问

默认情况下,pybind11会将C++的std::map直接映射为Python的dict,只能通过下标[]访问元素,示例代码如下:

struct A {
    std::map<std::string, int> attributes;

    A() { attributes["x"] = 1; attributes["y"] = 2; }
};

PYBIND11_MODULE(Example, m) {
    py::class_<A>(m, "A")
        .def_readonly("attributes", &A::attributes);
}

在Python中只能这样访问:

a.attributes["x"]
a.attributes["y"]

要实现a.attributes.x这类点语法访问,你可以通过给std::map绑定自定义的__getattr__和__setattr__方法来实现,具体代码如下:

C++绑定代码

#include <pybind11/pybind11.h>
#include <map>
#include <string>

namespace py = pybind11;

struct A {
    std::map<std::string, int> attributes;

    A() { attributes["x"] = 1; attributes["y"] = 2; }
};

// 为std::map<std::string, int>实现支持点语法的绑定
void bind_string_int_map(py::module_& m) {
    py::class_<std::map<std::string, int>>(m, "StringIntMap")
        .def(py::init<>())
        // 处理点语法获取属性
        .def("__getattr__", [](const std::map<std::string, int>& self, const std::string& name) {
            auto iter = self.find(name);
            if (iter != self.end()) {
                return iter->second;
            }
            throw py::attribute_error("属性 '" + name + "' 不存在");
        })
        // 处理点语法设置属性
        .def("__setattr__", [](std::map<std::string, int>& self, const std::string& name, int value) {
            self[name] = value;
        })
        // 可选:保留dict常用方法,比如获取键、键值对列表
        .def("keys", [](const std::map<std::string, int>& self) {
            py::list keys_list;
            for (const auto& pair : self) {
                keys_list.append(pair.first);
            }
            return keys_list;
        })
        .def("items", [](const std::map<std::string, int>& self) {
            py::list items_list;
            for (const auto& pair : self) {
                items_list.append(py::make_tuple(pair.first, pair.second));
            }
            return items_list;
        });
}

PYBIND11_MODULE(Example, m) {
    bind_string_int_map(m);

    py::class_<A>(m, "A")
        .def(py::init<>())
        .def_readonly("attributes", &A::attributes);
}

Python访问示例

import Example
a = Example.A()

# 点语法获取属性
print(a.attributes.x)  # 输出 1
print(a.attributes.y)  # 输出 2

# 点语法设置属性
a.attributes.z = 3
print(a.attributes.z)  # 输出 3

# 调用保留的dict方法
print(a.attributes.keys())  # 输出 ['x', 'y', 'z']

实现原理

通过给std::map的绑定类添加__getattr__和__setattr__方法,让Python解释器在处理点语法访问时,自动调用这些函数来查询或修改std::map中的键值对,同时还可以保留原有dict的常用方法,兼顾兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:05:18