質問

これは私の最近の二つの質問の組み合わせです:
[1] C の
Pythonのインスタンスメソッド [2] Pythonで標準エラー出力をリダイレクトするには?

私のPythonスクリプトからのstdoutとstderrの両方の出力をログに記録したいと思います。

私がお聞きしたい事はに応じて新しいタイプを作成するには、[1]は、かなり複雑なようです。 Pythonの新しいタイプを公開する必要はありませんでした場合、それは物事を単純化してい、すなわちそれはCでのみ存在するのでしょうか?

Pythonは「PyFile_WriteObject」であり「オブジェクト/ fileobject.c」にそれが行く何かを印刷したときに私が意味する、その引数に書き込むことが可能であるかどうかをチェックします:

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

また、それはこのようstdoutとstderrを得ることが可能である。

PyObject* out = PySys_GetObject("stdout");
PyObject* err = PySys_GetObject("stderr");
私は書くことができますので、私の質問は、その後で、それは上記の「PyObject_GetAttrString(fは、 『書き込み』)」とは、呼び出し可能である満たす必要PyObjectを構築するために何とかできます:

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'で、かつ)ています。

他のヒント

ここでアレックスの答えに基づいて、完全にPythonの3の(無Py_InitModuleはそう)、および標準エラー出力のリダイレクトと、Pythonの「インポートaview」なしで、Cコードを働いています

#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