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
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
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
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__
.
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())
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.
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)!
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__