All major Python types are available as thin C++ wrapper classes. These can also be used as function parameters – see Python 对象作为自变量 .
Available types include
handle
,
object
,
bool_
,
int_
,
float_
,
str
,
bytes
,
tuple
,
list
,
dict
,
slice
,
none
,
capsule
,
iterable
,
iterator
,
function
,
buffer
,
array
,和
array_t
.
警告
Be sure to review the Gotchas before using this heavily in your C++ API.
Dictionaries can be initialized in the
dict
构造函数:
using namespace pybind11::literals; // to bring in the `_a` literal py::dict d("spam"_a=py::none(), "eggs"_a=42);
A tuple of python objects can be instantiated using
py::make_tuple()
:
py::tuple tup = py::make_tuple(42, py::none(), "spam");
Each element is converted to a supported Python type.
A simple namespace can be instantiated using
using namespace pybind11::literals; // to bring in the `_a` literal py::object SimpleNamespace = py::module_::import("types").attr("SimpleNamespace"); py::object ns = SimpleNamespace("spam"_a=py::none(), "eggs"_a=42);
Attributes on a namespace can be modified with the
py::delattr()
,
py::getattr()
,和
py::setattr()
functions. Simple namespaces can be useful as lightweight stand-ins for class instances.
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
.
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
类。
// 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__");
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>();
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")
是
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 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 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);
另请参阅
文件
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.
When using the C++ interface for Python types, or calling Python functions, objects of type
object
are returned. It is possible to invoke implicit conversions to subclasses like
dict
. The same holds for the proxy objects returned by
operator[]
or
obj.attr()
. Casting to subtypes improves code readability and allows values to be passed to C++ functions that require a specific subtype rather than a generic
object
.
#include <pybind11/numpy.h> using namespace pybind11::literals; py::module_ os = py::module_::import("os"); py::module_ path = py::module_::import("os.path"); // like 'import os.path as path' py::module_ np = py::module_::import("numpy"); // like 'import numpy as np' py::str curdir_abs = path.attr("abspath")(path.attr("curdir")); py::print(py::str("Current directory: ") + curdir_abs); py::dict environ = os.attr("environ"); py::print(environ["HOME"]); py::array_t<float> arr = np.attr("ones")(3, "dtype"_a="float32"); py::print(py::repr(arr + py::int_(1)));
These implicit conversions are available for subclasses of
object
; there is no need to call
obj.cast()
explicitly as for custom classes, see
Casting back and forth
.
注意
If a trivial conversion via move constructor is not possible, both implicit and explicit casting (calling
obj.cast()
) will attempt a “rich” conversion. For instance,
py::list env = os.attr("environ");
will succeed and is equivalent to the Python code
env = list(os.environ)
that produces a list of the dict keys.
Python exceptions from wrapper classes will be thrown as a
py::error_already_set
。见
在 C++ 中处理来自 Python 的异常
for more information on handling exceptions raised when calling C++ wrapper classes.
When a wrapper type is default-constructed, it is
not
a valid Python object (i.e. it is not
py::none()
). It is simply the same as
PyObject*
null pointer. To check for this, use
static_cast<bool>(my_wrapper)
.
You may be tempted to use types like
py::str
and
py::dict
in C++ signatures (either pure C++, or in bound signatures), and assign them default values of
py::none()
. However, in a best case scenario, it will fail fast because
None
is not convertible to that type (e.g.
py::dict
), or in a worse case scenario, it will silently work but corrupt the types you want to work with (e.g.
py::str(py::none())
will yield
"None"
in Python).