To prevent a function from printing in the batch console in Python

Question:

Well, the headline seems to me sufficient.
I use some function that at some points print something in the console.
As I can’t modify them, I would like to know if there is a solution to not printing while using these functions.

Thanks a lot !

Nico

Asked By: NicoCati

||

Answers:

Yes, you can redirect sys.stdout:

import sys
import os

old_stdout = sys.stdout # backup current stdout
sys.stdout = open(os.devnull, "w")

my_nasty_function()

sys.stdout = old_stdout # reset old stdout

Just replace my_nasty_function with your actual function.

EDIT: Now should work on windows aswell.

EDIT: Use backup variable to reset stdout is better when someone wraps your function again

Answered By: Constantinius

Constantinius’ solution will work on *nix, but this should work on any platform:

import sys
import tempfile

sys.stdout = tempfile.TemporaryFile()

# Do crazy stuff here

sys.stdout.close()
#now the temp file is gone
sys.stdout = sys.__stdout__
Answered By: dtanders

Constantinius’ answer answer is ok, however there is no need to actually open null device. And BTW, if you want portable null device, there is os.devnull.

Actually, all you need is a class which will ignore whatever you write to it. So more portable version would be:

class NullIO(StringIO):
    def write(self, txt):
       pass

sys.stdout = NullIO()

my_nasty_function()

sys.stdout = sys.__stdout__

.

Answered By: vartec

You could use a modified version of this answer to create a “null” output context to wrap the call the function in.

That can be done by just passing os.devnull as the new_stdout argument to the stdout_redirected() context manager function when it’s used.

Answered By: martineau

Another option would be to wrap your function in a decorator.

from contextlib import redirect_stdout
from io import StringIO 

class NullIO(StringIO):
    def write(self, txt):
        pass


def silent(fn):
    """Decorator to silence functions."""
    def silent_fn(*args, **kwargs):
        with redirect_stdout(NullIO()):
            return fn(*args, **kwargs)
    return silent_fn


def nasty():
    """Useful function with nasty prints."""
    print('a lot of annoying output')
    return 42


# Wrap in decorator to prevent printing.
silent_nasty = silent(nasty)
# Same output, but prints only once.
print(nasty(), silent_nasty())
Answered By: Jarno

The currently accepted answer by Constantinius works great in most circumstances, but not in Jupyter notebooks.
Here’s how to get it to work (with a reusable function)…

TLDR~Instead of using sys.__stout__, backup sys.stdout and restore it later on.

In a Jupyter notebook, running sys.stdout == sys.__stdout__ returns false. This is because each cell has a separate output stream (instead of the one terminal instance, which is sys.__stdout__).
So for everyone working with Jupyter notebooks, make sure to back up the old sys.stdout path and restore it afterwards.
Here’s a function for it:

import sys, os
def deafen(function, *args):
    real_stdout = sys.stdout
    sys.stdout = open(os.devnull, "w")
    output = function(*args)
    sys.stdout = real_stdout
    return output

Pass to deafen a function along with its arguments/parameters (args). It backs up the old sys.stdout, switches to os.devnull and back again itself.

For a complete example we can create a second function (test_function):

def test_function(first_argument, second_argument, *args):
    print(first_argument)
    print(second_argument)
    print(args)

Now if we try using the test_function like normal (a.k.a. without deafen) we will get a bunch of output printed onto the screen:

print("Printing should work fine here")
test_function(32, 12, 1, 32, 1)

However, when using deafen, we’ll get no new output:

print("That'll be the last thing you see...")
deafen(test_function, 32, 12, 1, 32, 1)

On a side note, the deafen function still returns a functions output. You can also use deafen with sys.__stdout__ by replacing sys.stdout = real_stdout with sys.stdout = sys.__stdout__ (and may as well remove real_stdout = sys.stdout whilst you’re at it).

Hope that helps anyone who is looking for a slightly more robust or flexible solution (likely for Jupyter notebooks, or use with multiple functions)!

Answered By: Kamron Bhavnagri
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.