Python types¶
Available wrappers¶
All major Python types are available as thin C++ wrapper classes. These can also be used as function parameters – see Python objects as arguments.
Available types include handle
, object
, bool_
,
int_
, float_
, str
, bytes
, tuple
,
list
, dict
, slice
, none
, capsule
,
iterable
, iterator
, function
, buffer
,
array
, and array_t
.
Casting back and forth¶
In this kind of mixed code, it is often necessary to convert arbitrary C++
types to Python, which can be done using py::cast()
:
MyClass *cls = ..;
py::object obj = py::cast(cls);
The reverse direction uses the following syntax:
py::object obj = ...;
MyClass *cls = obj.cast<MyClass *>();
When conversion fails, both directions throw the exception cast_error
.
Accessing Python libraries from C++¶
It is also possible to import objects defined in the Python standard
library or available in the current Python environment (sys.path
) and work
with these in C++.
This example obtains a reference to the Python Decimal
class.
// Equivalent to "from decimal import Decimal"
py::object Decimal = py::module::import("decimal").attr("Decimal");
// Try to import scipy
py::object scipy = py::module::import("scipy");
return scipy.attr("__version__");
Calling Python functions¶
It is also possible to call Python classes, functions and methods
via operator()
.
// Construct a Python object of class Decimal
py::object pi = Decimal("3.14159");
// Use Python to make our directories
py::object os = py::module::import("os");
py::object makedirs = os.attr("makedirs");
makedirs("/tmp/path/to/somewhere");
One can convert the result obtained from Python to a pure C++ version
if a py::class_
or type conversion is defined.
py::function f = <...>;
py::object result_py = f(1234, "hello", some_instance);
MyClass &result = result_py.cast<MyClass>();
Calling Python methods¶
To call an object’s method, one can again use .attr
to obtain access to the
Python method.
// Calculate e^π in decimal
py::object exp_pi = pi.attr("exp")();
py::print(py::str(exp_pi));
In the example above pi.attr("exp")
is a bound method: it will always call
the method for that same instance of the class. Alternately one can create an
unbound method via the Python class (instead of instance) and pass the self
object explicitly, followed by other arguments.
py::object decimal_exp = Decimal.attr("exp");
// Compute the e^n for n=0..4
for (int n = 0; n < 5; n++) {
py::print(decimal_exp(Decimal(n));
}
Keyword arguments¶
Keyword arguments are also supported. In Python, there is the usual call syntax:
def f(number, say, to):
... # function code
f(1234, say="hello", to=some_instance) # keyword call in Python
In C++, the same call can be made using:
using namespace pybind11::literals; // to bring in the `_a` literal
f(1234, "say"_a="hello", "to"_a=some_instance); // keyword call in C++
Unpacking arguments¶
Unpacking of *args
and **kwargs
is also possible and can be mixed with
other arguments:
// * unpacking
py::tuple args = py::make_tuple(1234, "hello", some_instance);
f(*args);
// ** unpacking
py::dict kwargs = py::dict("number"_a=1234, "say"_a="hello", "to"_a=some_instance);
f(**kwargs);
// mixed keywords, * and ** unpacking
py::tuple args = py::make_tuple(1234);
py::dict kwargs = py::dict("to"_a=some_instance);
f(*args, "say"_a="hello", **kwargs);
Generalized unpacking according to PEP448 is also supported:
py::dict kwargs1 = py::dict("number"_a=1234);
py::dict kwargs2 = py::dict("to"_a=some_instance);
f(**kwargs1, "say"_a="hello", **kwargs2);
See also
The file tests/test_pytypes.cpp
contains a complete
example that demonstrates passing native Python types in more detail. The
file tests/test_callbacks.cpp
presents a few examples of calling
Python functions from C++, including keywords arguments and unpacking.