这是我的两个近期问题结合:点击 用C 结果[1] Python实例方法 [2] 如何在Python stderr重定向?

我想记录从一个Python脚本都输出和错误的输出。

我要问的是,根据创建一个新的类型的东西[1]似乎相当复杂。它简化了的东西,如果没有必要公开新类型的Python,即它将只在C存在?

我的意思是,当在Python的“PyFile_WriteObject”打印东西它去“对象/ fileobject.c”,有它检查是否有可能写入它的参数:

writer = PyObject_GetAttrString(f, "write");
if (writer == NULL)
...

另外,也有可能获得输出和错误是这样的:

PyObject* out = PySys_GetObject("stdout");
PyObject* err = PySys_GetObject("stderr");

我的问题是的话,就是它在某种程度上可以构建满足上述必要的PyObject“PyObject_GetAttrString(F,‘写入’)”和是可调用,所以我可以写:

PySys_SetObject("stdout", <my writer object / class / type / ?>);

http://docs.python.org/c -API / sys.html?突出= pysys_setobject#pySys_SetObject

这样一来,就没有必要公开新“作家型”到Python脚本的其余部分,所以我想这可能是一个简单一点写代码...?

有帮助吗?

解决方案

只是做一个模块对象(你这样做,无论如何,如果你使用的是C API - !),使其具有合适的write功能 - 该模块的对象将是适合作为第二个参数PySys_SetObject

在我回答你的其他问题,我指出你xxmodule.c,在Python的C程序源代码示例文件,这是一个有很多的例子,包括类型和各种功能模块 - 你可以从那里即使工作(鬼使神差地我)你考虑“作出新的类型”部分太困难; - )

修改:这里是一个简单的工作实施例(aview.py):

#include "Python.h"
#include <stdio.h>

static PyObject *
aview_write(PyObject *self, PyObject *args)
{
    const char *what;
    if (!PyArg_ParseTuple(args, "s", &what))
        return NULL;
    printf("==%s==", what);
    return Py_BuildValue("");
}

static PyMethodDef a_methods[] = {
    {"write", aview_write, METH_VARARGS, "Write something."},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
initaview(void)
{
    PyObject *m = Py_InitModule("aview", a_methods);
    if (m == NULL) return;
    PySys_SetObject("stdout", m);
}

在此aview模块安装正确:

$ python
Python 2.5.4 (r254:67917, Dec 23 2008, 14:57:27) 
[GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import aview
>>> print 'ciao'
==ciao====
==>>> 

...发射到标准输出任何字符串被写入与==迹象围绕它(这print调用.write两次:以换行符与'ciao',然后再次)。

其他提示

根据Alex的答案,在这里完全可以运行的C代码,而Python的 “进口aview”,在Python 3(所以没有Py_InitModule),与标准错误重定向:

#include <functional>
#include <iostream>
#include <string>
#include <Python.h>


PyObject* aview_write(PyObject* self, PyObject* args)
{
    const char *what;
    if (!PyArg_ParseTuple(args, "s", &what))
        return NULL;
    printf("==%s==", what);
    return Py_BuildValue("");
}


PyObject* aview_flush(PyObject* self, PyObject* args)
{
    return Py_BuildValue("");
}


PyMethodDef aview_methods[] =
{
    {"write", aview_write, METH_VARARGS, "doc for write"},
    {"flush", aview_flush, METH_VARARGS, "doc for flush"},
    {0, 0, 0, 0} // sentinel
};


PyModuleDef aview_module =
{
    PyModuleDef_HEAD_INIT, // PyModuleDef_Base m_base;
    "aview",               // const char* m_name;
    "doc for aview",       // const char* m_doc;
    -1,                    // Py_ssize_t m_size;
    aview_methods,        // PyMethodDef *m_methods
    //  inquiry m_reload;  traverseproc m_traverse;  inquiry m_clear;  freefunc m_free;
};

PyMODINIT_FUNC PyInit_aview(void) 
{
    PyObject* m = PyModule_Create(&aview_module);
    PySys_SetObject("stdout", m);
    PySys_SetObject("stderr", m);
    return m;
}


int main()
{
    PyImport_AppendInittab("aview", PyInit_aview);
    Py_Initialize();
    PyImport_ImportModule("aview");

    PyRun_SimpleString("print(\'hello to buffer\')");
    PyRun_SimpleString("make a SyntaxException in stderr");

    Py_Finalize();

    return 0;

}

请注意,不过,如果你打算有几个不同的解释,这是不够的,因为aview_write将无法知道要追加到该缓冲区。你需要像

这里是关于如何添加新的模块和类型,顺便说一句一个真棒参考。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top