我本质上是在尝试编写一个带有输入和输出的控制台界面,用于嵌入式python脚本。按照here的说明,我能够捕获标准输出:
Py_Initialize();
PyRun_SimpleString("\
class StdoutCatcher:\n\
def __init__(self):\n\
self.data = ''\n\
def write(self, stuff):\n\
self.data = self.data + stuff\n\
import sys\n\
sys.stdout = StdoutCatcher()");
PyRun_SimpleString("some script");
PyObject *sysmodule;
PyObject *pystdout;
PyObject *pystdoutdata;
char *string;
sysmodule = PyImport_ImportModule("sys");
pystdout = PyObject_GetAttrString(sysmodule, "stdout");
pystdoutdata = PyObject_GetAttrString(pystdout, "data");
stdoutstring = PyString_AsString(pystdoutdata);
Py_Finalize();
这个问题是我只在脚本运行完毕后才接收stdout ,而理想情况下,对于控制台,stdoutstring会在python脚本更新时更新。有没有办法做到这一点?
另外,我将如何捕获stdin?
如果有帮助,我正在使用接受Objective-C的编译器。我也有可用的增强库。
我已经找到了问题的标准部分。对于后代,这有效:
static PyObject*
redirection_stdoutredirect(PyObject *self, PyObject *args)
{
const char *string;
if(!PyArg_ParseTuple(args, "s", &string))
return NULL;
//pass string onto somewhere
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef RedirectionMethods[] = {
{"stdoutredirect", redirection_stdoutredirect, METH_VARARGS,
"stdout redirection helper"},
{NULL, NULL, 0, NULL}
};
//in main...
Py_Initialize();
Py_InitModule("redirection", RedirectionMethods);
PyRun_SimpleString("\
import redirection\n\
import sys\n\
class StdoutCatcher:\n\
def write(self, stuff):\n\
redirection.stdoutredirect(stuff)\n\
sys.stdout = StdoutCatcher()");
PyRun_SimpleString("some script");
Py_Finalize();
斯坦丁仍有问题...
答案 0 :(得分:1)
要处理Python中的所有可用输入,我建议使用fileinput模块。
如果要将输入作为逐行命令处理(例如在交互式解释器中),您可能会发现python函数raw_input很有用。
要使用类似的帮助程序类(例如您在上面使用的辅助类)重定向标准输入,要覆盖的函数是 readline ,而不是读取。有关详细信息,请参阅this link(以及raw_input)。
希望这有帮助, Supertwang
答案 1 :(得分:1)
到目前为止我发现的最简单方法如下:
PyObject *sys = PyImport_ImportModule("sys");
PyObject* io_stdout = PyFile_FromFile(stdout, "stdout", "a", nullptr);
PyObject_SetAttrString(sys, "stdout", io_stdout);
PyObject* io_stderr = PyFile_FromFile(stderr, "stderr", "a", nullptr);
PyObject_SetAttrString(sys, "stderr", io_stderr);
PyObject* io_stdin = PyFile_FromFile(stdin, "stdin", "r", nullptr);
PyObject_SetAttrString(sys, "stdin", io_stdin);
您可以使用以下方式进行测试:
# for test
PyRun_SimpleString("print sys.stdin.readline()");
答案 2 :(得分:0)
如果您坚持使用您概述的方法,从io.IOBase继承您的类可能是一个好主意。