我使用python lib导入一个在stdout上打印的C共享库.我想要一个干净的输出,以便与管道一起使用或重定向文件.打印是在python之外的共享库中完成的.
一开始,我的方法是:
# file: test.py
import os
from ctypes import *
from tempfile import mktemp
libc = CDLL("libc.so.6")
print # That's here on purpose, otherwise hello word is always printed
tempfile = open(mktemp(),'w')
savestdout = os.dup(1)
os.close(1)
if os.dup(tempfile.fileno()) != 1:
assert False, "couldn't redirect stdout - dup() error"
# let's pretend this is a call to my library
libc.printf("hello world\n")
os.close(1)
os.dup(savestdout)
os.close(savestdout)
Run Code Online (Sandbox Code Playgroud)
第一种方法是半工作:
- 由于某种原因,它在移动stdout之前需要一个"print"语句,否则总是打印hello word.因此,它将打印一个空行而不是库通常输出的所有模糊.
- 更令人讨厌,重定向到文件时失败:
$python test.py > foo && cat foo
hello world …Run Code Online (Sandbox Code Playgroud) 我有一个Python脚本,它使用我的雇主提供的一些闭箱Python函数(即我无法编辑这些函数).当我调用这些函数时,它们正在打印输出到我想要压制的linux终端.我尝试过重定向stdout/stderr;
orig_out = sys.stdout
sys.stdout = StringIO()
rogue_function()
sys.stdout = orig_out
Run Code Online (Sandbox Code Playgroud)
但这没有抓住输出.我认为我通过Python调用的函数(上面的rogue_function())实际上是编译C代码的包装器,它们实际上正在进行打印.
有没有人知道我可以通过函数(以及函数调用的任何子函数)对stdout/stderr的任何打印进行"深度捕获"?
更新:
我最终采用了下面选定答案中概述的方法并编写了一个上下文管理器来压制stdout和stderr:
# Define a context manager to suppress stdout and stderr.
class suppress_stdout_stderr(object):
'''
A context manager for doing a "deep suppression" of stdout and stderr in
Python, i.e. will suppress all print, even if the print originates in a
compiled C/Fortran sub-function.
This will not suppress raised exceptions, since exceptions are printed
to stderr just before a script exits, and after the context manager …Run Code Online (Sandbox Code Playgroud)