| | Utilities |
| | ######### |
| |
|
| | Using Python's print function in C++ |
| | ==================================== |
| |
|
| | The usual way to write output in C++ is using ``std::cout`` while in Python one |
| | would use ``print``. Since these methods use different buffers, mixing them can |
| | lead to output order issues. To resolve this, pybind11 modules can use the |
| | :func:`py::print` function which writes to Python's ``sys.stdout`` for consistency. |
| |
|
| | Python's ``print`` function is replicated in the C++ API including optional |
| | keyword arguments ``sep``, ``end``, ``file``, ``flush``. Everything works as |
| | expected in Python: |
| |
|
| | .. code-block:: cpp |
| |
|
| | py::print(1, 2.0, "three"); |
| | py::print(1, 2.0, "three", "sep"_a="-"); |
| |
|
| | auto args = py::make_tuple("unpacked", true); |
| | py::print("->", *args, "end"_a="<-"); |
| |
|
| | .. _ostream_redirect: |
| |
|
| | Capturing standard output from ostream |
| | ====================================== |
| |
|
| | Often, a library will use the streams ``std::cout`` and ``std::cerr`` to print, |
| | but this does not play well with Python's standard ``sys.stdout`` and ``sys.stderr`` |
| | redirection. Replacing a library's printing with `py::print <print>` may not |
| | be feasible. This can be fixed using a guard around the library function that |
| | redirects output to the corresponding Python streams: |
| |
|
| | .. code-block:: cpp |
| |
|
| | #include <pybind11/iostream.h> |
| |
|
| | ... |
| |
|
| | |
| | m.def("noisy_func", []() { |
| | py::scoped_ostream_redirect stream( |
| | std::cout, |
| | py::module::import("sys").attr("stdout") |
| | ); |
| | call_noisy_func(); |
| | }); |
| |
|
| | This method respects flushes on the output streams and will flush if needed |
| | when the scoped guard is destroyed. This allows the output to be redirected in |
| | real time, such as to a Jupyter notebook. The two arguments, the C++ stream and |
| | the Python output, are optional, and default to standard output if not given. An |
| | extra type, `py::scoped_estream_redirect <scoped_estream_redirect>`, is identical |
| | except for defaulting to ``std::cerr`` and ``sys.stderr``; this can be useful with |
| | `py::call_guard`, which allows multiple items, but uses the default constructor: |
| |
|
| | .. code-block:: py |
| |
|
| | |
| | m.def("noisy_func", &call_noisy_function, |
| | py::call_guard<py::scoped_ostream_redirect, |
| | py::scoped_estream_redirect>()); |
| |
|
| | The redirection can also be done in Python with the addition of a context |
| | manager, using the `py::add_ostream_redirect() <add_ostream_redirect>` function: |
| |
|
| | .. code-block:: cpp |
| |
|
| | py::add_ostream_redirect(m, "ostream_redirect"); |
| |
|
| | The name in Python defaults to ``ostream_redirect`` if no name is passed. This |
| | creates the following context manager in Python: |
| |
|
| | .. code-block:: python |
| |
|
| | with ostream_redirect(stdout=True, stderr=True): |
| | noisy_function() |
| |
|
| | It defaults to redirecting both streams, though you can use the keyword |
| | arguments to disable one of the streams if needed. |
| |
|
| | .. note:: |
| |
|
| | The above methods will not redirect C-level output to file descriptors, such |
| | as ``fprintf``. For those cases, you'll need to redirect the file |
| | descriptors either directly in C or with Python's ``os.dup2`` function |
| | in an operating-system dependent way. |
| |
|
| | .. _eval: |
| |
|
| | Evaluating Python expressions from strings and files |
| | ==================================================== |
| |
|
| | pybind11 provides the `eval`, `exec` and `eval_file` functions to evaluate |
| | Python expressions and statements. The following example illustrates how they |
| | can be used. |
| |
|
| | .. code-block:: cpp |
| |
|
| | |
| | #include <pybind11/eval.h> |
| |
|
| | ... |
| |
|
| | |
| | py::object scope = py::module::import("__main__").attr("__dict__"); |
| |
|
| | |
| | int result = py::eval("my_variable + 10", scope).cast<int>(); |
| |
|
| | |
| | py::exec( |
| | "print('Hello')\n" |
| | "print('world!');", |
| | scope); |
| |
|
| | |
| | py::eval_file("script.py", scope); |
| |
|
| | C++11 raw string literals are also supported and quite handy for this purpose. |
| | The only requirement is that the first statement must be on a new line following |
| | the raw string delimiter ``R"(``, ensuring all lines have common leading indent: |
| |
|
| | .. code-block:: cpp |
| |
|
| | py::exec(R"( |
| | x = get_answer() |
| | if x == 42: |
| | print('Hello World!') |
| | else: |
| | print('Bye!') |
| | )", scope |
| | ); |
| |
|
| | .. note:: |
| |
|
| | `eval` and `eval_file` accept a template parameter that describes how the |
| | string/file should be interpreted. Possible choices include ``eval_expr`` |
| | (isolated expression), ``eval_single_statement`` (a single statement, return |
| | value is always ``none``), and ``eval_statements`` (sequence of statements, |
| | return value is always ``none``). `eval` defaults to ``eval_expr``, |
| | `eval_file` defaults to ``eval_statements`` and `exec` is just a shortcut |
| | for ``eval<eval_statements>``. |
| |
|