在old question中关于如何在C ++代码中捕获python stdout,there is a good answer并且它有效 - 但仅限于Python 2。
我想在Python 3中使用类似的东西。任何人都可以帮助我吗?
更新
我正在使用的代码如下。它来自上面引用的Mark答案,唯一的变化是使用301
代替PyBytes_AsString
,cited in documentation。
PyString_AsString
我使用Python 3库构建它:
#include <Python.h>
#include <string>
int main(int argc, char** argv)
{
std::string stdOutErr =
"import sys\n\
class CatchOutErr:\n\
def __init__(self):\n\
self.value = ''\n\
def write(self, txt):\n\
self.value += txt\n\
catchOutErr = CatchOutErr()\n\
sys.stdout = catchOutErr\n\
sys.stderr = catchOutErr\n\
"; //this is python code to redirect stdouts/stderr
Py_Initialize();
PyObject *pModule = PyImport_AddModule("__main__"); //create main module
PyRun_SimpleString(stdOutErr.c_str()); //invoke code to redirect
PyRun_SimpleString("print(1+1)"); //this is ok stdout
PyRun_SimpleString("1+a"); //this creates an error
PyObject *catcher = PyObject_GetAttrString(pModule,"catchOutErr"); //get our catchOutErr created above
PyErr_Print(); //make python print any errors
PyObject *output = PyObject_GetAttrString(catcher,"value"); //get the stdout and stderr from our catchOutErr object
printf("Here's the output:\n %s", PyBytes_AsString(output)); //it's not in our C++ portion
Py_Finalize();
return 0;
}
,输出为:
g++ -I/usr/include/python3.6m -Wall -Werror -fpic code.cpp -lpython3.6m
如果有人需要有关该问题的更多信息,请告诉我,我会在此处提供。
答案 0 :(得分:0)
您的问题是.value
不是bytes
对象,而是string
(即Python2 unicode
)对象。因此PyBytes_AsString
失败。我们可以使用bytes
将其转换为PyUnicode_AsEncodedString
对象。
PyObject *output = PyObject_GetAttrString(catcher,"value"); //get the stdout and stderr from our catchOutErr
PyObject* encoded = PyUnicode_AsEncodedString(output,"utf-8","strict");
printf("Here's the output:\n %s", PyBytes_AsString(encoded));
请注意,您应该检查这些结果PyObject*
是否为NULL,以查看是否发生了错误。