Nimitz14
Nimitz14

Reputation: 2338

How to set values of py::dict in C++?

I want to use a py::dict from C++. But operator[] does not seem to be defined, and I can't find any information here or in the pybind11 docs of how to add a key/value pair or return a value for a key?

edit: Maybe also important to mention I've got integers as keys.

edit2: Needed to use py::int_()

Upvotes: 1

Views: 2684

Answers (2)

TingQian LI
TingQian LI

Reputation: 680

You can see operator[] has two overloads takes either a py::handle or string literal, so d["xxx"] or d[py::int_{0}] work but not d[0] (which would be wrongly resolved as a invalid string literal at compile time,and would cause run-time segment-fault)

template <typename Derived>
class object_api : public pyobject_tag {
...
    /** \rst
        Return an internal functor to invoke the object's sequence protocol. Casting
        the returned ``detail::item_accessor`` instance to a `handle` or `object`
        subclass causes a corresponding call to ``__getitem__``. Assigning a `handle`
        or `object` subclass causes a call to ``__setitem__``.
    \endrst */
    item_accessor operator[](handle key) const;
    /// See above (the only difference is that they key is provided as a string literal)
    item_accessor operator[](const char *key) const;

also you cannot use std::string as key:

std::string key="xxx";
d[key] = 1;  // failed to compile, must change to d[pybind11::str(key)]

to make things easier, use pybind11::cast() to explicitly convert any supported C++ type into corresponding python type, as following:

std::string key="xxx";
d[pybind11::cast(1)] = 2
d[pybind11::cast(key)] = 3

Upvotes: 2

Piotr Barejko
Piotr Barejko

Reputation: 648

I see operator[] defined for py::dict, example:

m.def("test", [](){
    py::dict d;
    d[py::int_{0}] = "foo";
    return d;
});
>>> example.test()
{10: 'foo'}

Upvotes: 3

Related Questions