从 Python 函数中抑制 stdout/stderr 打印 [英] Suppress stdout / stderr print from Python functions

查看:31
本文介绍了从 Python 函数中抑制 stdout/stderr 打印的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Python 脚本,它使用了我雇主提供的一些封闭的 Python 函数(即我无法编辑这些函数).当我调用这些函数时,它们正在将输出打印到我想抑制的 linux 终端.我试过通过重定向标准输出/标准错误;

I have a Python script that is using some closed-box Python functions (i.e. I can't edit these functions) provided by my employer. When I call these functions, they are printing output to my linux terminal that I would like to suppress. I've tried redirecting stdout / stderr via;

orig_out = sys.stdout
sys.stdout = StringIO()
rogue_function()
sys.stdout = orig_out

但这无法捕获输出.我认为我通过 Python 调用的函数(上面的 rogue_function())实际上是编译 C 代码的包装器,它们实际上是在进行打印.

but this fails to catch the output. I think the functions I'm calling via-Python (rogue_function() from above) are really wrappers for compiled C-code, which are actually doing the printing.

有谁知道我可以对由函数(以及函数调用的任何子函数)传递给 stdout/stderr 的任何打印进行深度捕获"的方法吗?

Does anyone know of a way I can do a "deep-capture" of any print handed to stdout / stderr by a function (and any sub-functions that function calls)?

更新:

我最终采用了下面所选答案中概述的方法,并编写了一个上下文管理器来抑制 stdout 和 stderr:

I ended up taking the method outlined in the selected answer below and writing a context manager to supress stdout and 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(我认为它发生在我的上下文管理器退出之后)有关.如果有人能证实这一点,我很想听听细节......

This works "pretty good". It does suppress the printout from the rogue functions that were cluttering up my script. I noticed in testing it that it lets through raised exceptions as well as some logger print, and I'm not entirely clear why. I think it has something to do with when these messages get sent to stdout / stderr (I think it happens after my context manager exits). If anyone can confirm this, I'd be interested in hearing the details ...

推荐答案

这种方法(通过相关侧边栏找到)可能工作.它在 sys.stdout 等中重新分配文件描述符,而不仅仅是包装器.

This approach (found through the related sidebar) might work. It reassigns the file descriptors rather than just the wrappers to them in sys.stdout, etc.

这篇关于从 Python 函数中抑制 stdout/stderr 打印的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆