github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/pybind11/docs/advanced/pycpp/utilities.rst (about)

     1  Utilities
     2  #########
     3  
     4  Using Python's print function in C++
     5  ====================================
     6  
     7  The usual way to write output in C++ is using ``std::cout`` while in Python one
     8  would use ``print``. Since these methods use different buffers, mixing them can
     9  lead to output order issues. To resolve this, pybind11 modules can use the
    10  :func:`py::print` function which writes to Python's ``sys.stdout`` for consistency.
    11  
    12  Python's ``print`` function is replicated in the C++ API including optional
    13  keyword arguments ``sep``, ``end``, ``file``, ``flush``. Everything works as
    14  expected in Python:
    15  
    16  .. code-block:: cpp
    17  
    18      py::print(1, 2.0, "three"); // 1 2.0 three
    19      py::print(1, 2.0, "three", "sep"_a="-"); // 1-2.0-three
    20  
    21      auto args = py::make_tuple("unpacked", true);
    22      py::print("->", *args, "end"_a="<-"); // -> unpacked True <-
    23  
    24  .. _ostream_redirect:
    25  
    26  Capturing standard output from ostream
    27  ======================================
    28  
    29  Often, a library will use the streams ``std::cout`` and ``std::cerr`` to print,
    30  but this does not play well with Python's standard ``sys.stdout`` and ``sys.stderr``
    31  redirection. Replacing a library's printing with ``py::print <print>`` may not
    32  be feasible. This can be fixed using a guard around the library function that
    33  redirects output to the corresponding Python streams:
    34  
    35  .. code-block:: cpp
    36  
    37      #include <pybind11/iostream.h>
    38  
    39      ...
    40  
    41      // Add a scoped redirect for your noisy code
    42      m.def("noisy_func", []() {
    43          py::scoped_ostream_redirect stream(
    44              std::cout,                               // std::ostream&
    45              py::module_::import("sys").attr("stdout") // Python output
    46          );
    47          call_noisy_func();
    48      });
    49  
    50  .. warning::
    51  
    52      The implementation in ``pybind11/iostream.h`` is NOT thread safe. Multiple
    53      threads writing to a redirected ostream concurrently cause data races
    54      and potentially buffer overflows. Therefore it is currently a requirement
    55      that all (possibly) concurrent redirected ostream writes are protected by
    56      a mutex. #HelpAppreciated: Work on iostream.h thread safety. For more
    57      background see the discussions under
    58      `PR #2982 <https://github.com/pybind/pybind11/pull/2982>`_ and
    59      `PR #2995 <https://github.com/pybind/pybind11/pull/2995>`_.
    60  
    61  This method respects flushes on the output streams and will flush if needed
    62  when the scoped guard is destroyed. This allows the output to be redirected in
    63  real time, such as to a Jupyter notebook. The two arguments, the C++ stream and
    64  the Python output, are optional, and default to standard output if not given. An
    65  extra type, ``py::scoped_estream_redirect <scoped_estream_redirect>``, is identical
    66  except for defaulting to ``std::cerr`` and ``sys.stderr``; this can be useful with
    67  ``py::call_guard``, which allows multiple items, but uses the default constructor:
    68  
    69  .. code-block:: cpp
    70  
    71      // Alternative: Call single function using call guard
    72      m.def("noisy_func", &call_noisy_function,
    73            py::call_guard<py::scoped_ostream_redirect,
    74                           py::scoped_estream_redirect>());
    75  
    76  The redirection can also be done in Python with the addition of a context
    77  manager, using the ``py::add_ostream_redirect() <add_ostream_redirect>`` function:
    78  
    79  .. code-block:: cpp
    80  
    81      py::add_ostream_redirect(m, "ostream_redirect");
    82  
    83  The name in Python defaults to ``ostream_redirect`` if no name is passed.  This
    84  creates the following context manager in Python:
    85  
    86  .. code-block:: python
    87  
    88      with ostream_redirect(stdout=True, stderr=True):
    89          noisy_function()
    90  
    91  It defaults to redirecting both streams, though you can use the keyword
    92  arguments to disable one of the streams if needed.
    93  
    94  .. note::
    95  
    96      The above methods will not redirect C-level output to file descriptors, such
    97      as ``fprintf``. For those cases, you'll need to redirect the file
    98      descriptors either directly in C or with Python's ``os.dup2`` function
    99      in an operating-system dependent way.
   100  
   101  .. _eval:
   102  
   103  Evaluating Python expressions from strings and files
   104  ====================================================
   105  
   106  pybind11 provides the ``eval``, ``exec`` and ``eval_file`` functions to evaluate
   107  Python expressions and statements. The following example illustrates how they
   108  can be used.
   109  
   110  .. code-block:: cpp
   111  
   112      // At beginning of file
   113      #include <pybind11/eval.h>
   114  
   115      ...
   116  
   117      // Evaluate in scope of main module
   118      py::object scope = py::module_::import("__main__").attr("__dict__");
   119  
   120      // Evaluate an isolated expression
   121      int result = py::eval("my_variable + 10", scope).cast<int>();
   122  
   123      // Evaluate a sequence of statements
   124      py::exec(
   125          "print('Hello')\n"
   126          "print('world!');",
   127          scope);
   128  
   129      // Evaluate the statements in an separate Python file on disk
   130      py::eval_file("script.py", scope);
   131  
   132  C++11 raw string literals are also supported and quite handy for this purpose.
   133  The only requirement is that the first statement must be on a new line following
   134  the raw string delimiter ``R"(``, ensuring all lines have common leading indent:
   135  
   136  .. code-block:: cpp
   137  
   138      py::exec(R"(
   139          x = get_answer()
   140          if x == 42:
   141              print('Hello World!')
   142          else:
   143              print('Bye!')
   144          )", scope
   145      );
   146  
   147  .. note::
   148  
   149      `eval` and `eval_file` accept a template parameter that describes how the
   150      string/file should be interpreted. Possible choices include ``eval_expr``
   151      (isolated expression), ``eval_single_statement`` (a single statement, return
   152      value is always ``none``), and ``eval_statements`` (sequence of statements,
   153      return value is always ``none``). `eval` defaults to  ``eval_expr``,
   154      `eval_file` defaults to ``eval_statements`` and `exec` is just a shortcut
   155      for ``eval<eval_statements>``.