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