我有一个 Python 脚本,它使用了我的雇主提供的一些封闭式 Python 函数(即我无法编辑这些函数)。当我调用这些函数时,它们会将输出打印到我想要抑制的 linux 终端。我尝试通过重定向标准输出/标准错误;
orig_out = sys.stdout
sys.stdout = StringIO()
rogue_function()
sys.stdout = orig_out
但这无法捕捉输出。我认为我通过 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 has
exited (at least, I think that is why it lets exceptions through).
'''
def __init__(self):
# Open a pair of null files
self.null_fds = [os.open(os.devnull,os.O_RDWR) for x in range(2)]
# Save the actual stdout (1) and stderr (2) file descriptors.
self.save_fds = [os.dup(1), os.dup(2)]
def __enter__(self):
# Assign the null pointers to stdout and stderr.
os.dup2(self.null_fds[0],1)
os.dup2(self.null_fds[1],2)
def __exit__(self, *_):
# Re-assign the real stdout/stderr back to (1) and (2)
os.dup2(self.save_fds[0],1)
os.dup2(self.save_fds[1],2)
# Close all file descriptors
for fd in self.null_fds + self.save_fds:
os.close(fd)
要使用它,您只需:
with suppress_stdout_stderr():
rogue_function()
这工作“相当不错”。它确实抑制了使我的脚本混乱的流氓函数的打印输出。我在测试它时注意到它允许通过引发的异常以及一些记录器打印,我并不完全清楚为什么。我认为这与这些消息何时发送到 stdout / stderr 有关(我认为它发生在我的上下文管理器退出之后)。如果有人能证实这一点,我很想听听细节......