我有一个程序,在运行过程中有时需要调用python来执行一些任务。我需要一个调用python的函数,然后捕获pythons stdout并将其放入某个文件中。 这是函数的声明
pythonCallBackFunc(const char* pythonInput)
我的问题是捕获给定命令(pythonInput)的所有python输出。 我没有使用python API的经验,我不知道什么是正确的技术。 我尝试的第一件事是使用Py-run-SimpleString重定向python的sdtout和stderr 这是我写的代码的一个例子。
#include "boost\python.hpp"
#include <iostream>
void pythonCallBackFunc(const char* inputStr){
PyRun_SimpleString(inputStr);
}
int main () {
...
//S0me outside functions does this
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("old_stdout = sys.stdout");
PyRun_SimpleString("fsock = open('python_out.log','a')");
PyRun_SimpleString("sys.stdout = fsock");
...
//my func
pythonCallBackFunc("print 'HAHAHAHAHA'");
pythonCallBackFunc("result = 5");
pythonCallBackFunc("print result");
pythonCallBackFunc("result = 'Hello '+'World!'");
pythonCallBackFunc("print result");
pythonCallBackFunc("'KUKU '+'KAKA'");
pythonCallBackFunc("5**3");
pythonCallBackFunc("prinhghult");
pythonCallBackFunc("execfile('stdout_close.py')");
...
//Again anothers function code
PyRun_SimpleString("sys.stdout = old_stdout");
PyRun_SimpleString("fsock.close()");
Py_Finalize();
return 0;
}
有更好的办法吗?此外,由于某些原因,PyRun_SimpleString在获取某些数学表达式时不执行任何操作,例如PyRun_SimpleString(“5**3”)不打印任何内容(python conlsul打印结果:125)
也许这很重要,我正在使用visual studio 2008。 谢谢, 亚历克斯
我根据马克的建议做了些改变:
#include <python.h>
#include <string>
using namespace std;
void PythonPrinting(string inputStr){
string stdOutErr =
"import sys\n\
class CatchOut:\n\
def __init__(self):\n\
self.value = ''\n\
def write(self, txt):\n\
self.value += txt\n\
catchOut = CatchOut()\n\
sys.stdout = catchOut\n\
sys.stderr = catchOut\n\
"; //this is python code to redirect stdouts/stderr
PyObject *pModule = PyImport_AddModule("__main__"); //create main module
PyRun_SimpleString(stdOutErr.c_str()); //invoke code to redirect
PyRun_SimpleString(inputStr.c_str());
PyObject *catcher = PyObject_GetAttrString(pModule,"catchOut");
PyObject *output = PyObject_GetAttrString(catcher,"value");
printf("Here's the output: %s\n", PyString_AsString(output));
}
int main(int argc, char** argv){
Py_Initialize();
PythonPrinting("print 123");
PythonPrinting("1+5");
PythonPrinting("result = 2");
PythonPrinting("print result");
Py_Finalize();
return 0;
}
运行main后得到的输出:
Here's the output: 123
Here's the output:
Here's the output:
Here's the output: 2
对我有好处,但只有一个问题
Here's the output: 123
Here's the output: 6
Here's the output:
Here's the output: 2
我不知道为什么,但是在运行这个命令:PythonPrinting(“1+5”)之后,PyString_AsString(output)命令返回一个空字符串(char*)而不是6。。。:(有什么事情我不能放松这个输出吗?
塔克人, 亚历克斯
这是我最近开发的一个C++友好解决方案。
我在我的博客上解释了其中的一些细节:Python sys.stdout redirection in C++其中我还指向GitHub上的存储库,在那里可以找到最新的版本。 以下是发布此答案时基于当前代码的完整示例:
<>这允许用任何类型的可调用C++实体截取^ {< CD1>}输出:自由函数、类成员函数、命名函数对象或匿名函数,如上面我使用C++11 lambda的例子。注意,这是一个简单的例子来展示基本概念。在产品级代码中,它当然需要更多关注
PyObject
的引用计数、摆脱全局状态等等。我知道这个问题已经过时了,但有一部分问题还没有得到回答:
以下是步骤(对于Python3.4):
使用Mark的解决方案将stdout/stderr重定向到Python变量:https://stackoverflow.com/a/4307737/1046299
从Python源代码复制函数
PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
。它位于文件pythonrun.c
修改
PyRun_InteractiveOneObject
函数名和签名,以便新函数将const char*
(您的命令)作为第一个参数,而不是FILE*
。然后需要在函数实现中使用PyParser_ASTFromStringObject
,而不是PyParser_ASTFromFileObject
。注意,您需要从Python中复制函数run_mod
,因为它是在函数中调用的。使用命令调用新函数,例如
1+1
。Stdout现在应该接收输出2
。相关问题 更多 >
编程相关推荐