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>``.