如何在Python中重定向stderr?通过Python C API?
这是我最近的两个问题的组合:
[1] C 语言中的 Python 实例方法
[2] 如何在 Python 中重定向 stderr?
我想记录python 脚本的 stdout 和 stderr 输出。
我想问的是,根据[1]创建一个新类型似乎相当复杂。如果不需要向 Python 公开新类型,即它只存在于 C 中,是否会简化事情?
我的意思是,当Python打印一些东西时,它会转到“Objects/fileobject.c”,并在“PyFile_WriteObject”中检查是否可以写入其参数:
writer = PyObject_GetAttrString(f, "write");
if (writer == NULL)
...
另外,可以像这样获得stdout和stderr:
PyObject* out = PySys_GetObject("stdout");
PyObject* err = PySys_GetObject("stderr");
我的问题那么,是否可以以某种方式构造必要的 PyObject,它满足上述 'PyObject_GetAttrString(f, "write")' 并且可调用,以便我可以编写:
PySys_SetObject("stdout", <my writer object / class / type / ?>);
http://docs.python.org/c-api/sys.html?highlight=pysys_setobject#PySys_SetObject
这样,就有不需要向 Python 脚本的其余部分公开新的“编写器类型”,所以我认为编写代码可能会更简单......?
This is a combination of my two recent questions:
[1] Python instance method in C
[2] How to redirect stderr in Python?
I would like to log the output of both stdout and stderr from a python script.
The thing I want to ask is, to create a new type according to [1] seems fairly complicated. Does it simplifies the things if there was no need to expose the new type to Python, i.e. it would only exist in C?
I mean, when Python prints something it goes to "Objects/fileobject.c" and there in "PyFile_WriteObject" it check whether it is possible to write to its argument:
writer = PyObject_GetAttrString(f, "write");
if (writer == NULL)
...
Also, it is possible to get stdout and stderr like this:
PyObject* out = PySys_GetObject("stdout");
PyObject* err = PySys_GetObject("stderr");
My question is then, is it somehow possible to construct necessary PyObject which satisfies the above 'PyObject_GetAttrString(f, "write")' and is callable so I can write:
PySys_SetObject("stdout", <my writer object / class / type / ?>);
http://docs.python.org/c-api/sys.html?highlight=pysys_setobject#PySys_SetObject
This way, there would be no need to expose the new "writer type" to the rest of Python script so I thought it might be a bit simpler to write the code...?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
只需创建一个模块对象(无论如何,如果您使用的是 C API,您都会这样做!-)并使其具有合适的
write
函数 - 该模块对象将适合作为第二个PySys_SetObject
的参数。在我对你的另一个问题的回答中,我向你指出了 xxmodule.c,这是 Python C 源代码中的一个示例文件,它是一个包含大量示例的模块,包括各种类型和函数 - 你可以即使(对我来说很神秘)您认为“创建新类型”部分太困难,也可以从那里开始工作;-)。
编辑:这是一个简单的工作示例(
aview.py
):正确安装此
aview
模块后:...发送到标准的任何字符串输出周围有
==
符号(并且这个print
调用.write
两次:使用'ciao'
,然后再次换行)。Just make a module object (you're doing that anyway, if you're using the C API!-) and make it have a suitable
write
function -- that module object will be suitable as the second argument toPySys_SetObject
.In my answer to your other question I pointed you to
xxmodule.c
, an example file in Python's C sources, which is a module with a lot of examples including types and functions of various kinds -- you can work from there even if (mysteriously to me) you consider the "make a new type" part too difficult;-).Edit: here's a trivial working example (
aview.py
):Once this
aview
module is properly installed:...any string emitted to standard output is written with
==
signs around it (and thisprint
calls.write
twice: with'ciao'
, and then again with a newline).根据Alex的回答,这里是完全有效的C代码,没有Python“导入aview”,在Python 3中(所以没有Py_InitModule),并且带有stderr重定向:
但请注意,如果您计划有几个不同的解释器,这会获胜这还不够,因为
aview_write
将无法知道要附加到哪个缓冲区。你需要像这样的东西。顺便说一句,这里是关于如何添加新模块和类型的很棒的参考。
Based on Alex's answer, here is fully working C code, without the Python "import aview", in Python 3 (so no Py_InitModule), and with stderr redirection :
Note, though, that if you plan to have several distinct interpreters, this won't be enough, because
aview_write
won't be able to know which buffer to append into. You'll need something like that.Here is an awesome reference on how to add new modules and types, btw.