Search code examples
c++pybind11

Accessing instance variables of a class from pybind11 wrappers


I haven't found a way to do a fairly simple thing with pybind11. Suppose I have an aggregated class, and I want to get to an instance variable of a class so I can drill down into it:

struct foo {
  int x;
};

struct baz {
  foo var;
}

PYBIND11_MODULE(test, m) {
  py::class_<baz>(m, "baz")
  .def(py::init<>())
  .def("GetX", /* need a lambda to return var.x */ )
  ;
}

I haven't found anything in the docs which does this, and it seems like an obvious thing to do. I could create accessor methods in baz, but that is extra work. I'd like to do it in a lambda in the wrapper code.


Solution

  • The following lambda creates the necessary GetX member function, which expects one argument: a baz instance. The argument is supplied by pybind11 when GetX is called on an instance of the wrapper class.

      ...
      .def("GetX", [](const baz &b) { return b.var.x; });
    

    Usage:

    >>> import ex
    >>> v = ex.baz()
    >>> v.GetX()
    0
    

    See also the pybind11 doc section on binding lambda functions.