Suppress stdout / stderr print from Python functions

前端 未结 9 1911
情歌与酒
情歌与酒 2020-11-29 06:59

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 pri

9条回答
  •  广开言路
    2020-11-29 07:43

    As of python 3.5 we can do this with minimal work using built-ins in contextlib, namely redirect_stdout and redirect_stderr. We only need to combine these two built-in context managers in a custom context manager of ours, which can be easily done using the nice pattern in Martijn's answer here. Redirecting both outputs to os.devnull should be safe and portable enough.

    from contextlib import contextmanager,redirect_stderr,redirect_stdout
    from os import devnull
    
    @contextmanager
    def suppress_stdout_stderr():
        """A context manager that redirects stdout and stderr to devnull"""
        with open(devnull, 'w') as fnull:
            with redirect_stderr(fnull) as err, redirect_stdout(fnull) as out:
                yield (err, out)
    

    Note that suppressing stderr will still give you full tracebacks when something breaks, which is a good thing:

    import sys
    
    def rogue_function():
        print('spam to stdout')
        print('important warning', file=sys.stderr)
        1 + 'a'
        return 42
    
    with suppress_stdout_stderr():
        rogue_function()
    

    When run the above only prints

    Traceback (most recent call last):
      File "tmp.py", line 20, in 
        rogue_function()
      File "foo.py", line 16, in rogue_function
        1 + 'a'
    TypeError: unsupported operand type(s) for +: 'int' and 'str'
    

    to the terminal. Unhandled exceptions should never go unnoticed.

提交回复
热议问题