Silence the Stdout of a Function in Python Without Trashing Sys.Stdout and Restoring Each Function Call

Silence the stdout of a function in Python without trashing sys.stdout and restoring each function call

Assigning the stdout variable as you're doing has no effect whatsoever, assuming foo contains print statements -- yet another example of why you should never import stuff from inside a module (as you're doing here), but always a module as a whole (then use qualified names). The copy is irrelevant, by the way. The correct equivalent of your snippet is:

import sys
save_stdout = sys.stdout
sys.stdout = open('trash', 'w')
foo()
sys.stdout = save_stdout

Now, when the code is correct, is the time to make it more elegant or fast. For example, you could use an in-memory file-like object instead of file 'trash':

import sys
import io
save_stdout = sys.stdout
sys.stdout = io.BytesIO()
foo()
sys.stdout = save_stdout

for elegance, a context is best, e.g:

import contextlib
import io
import sys

@contextlib.contextmanager
def nostdout():
save_stdout = sys.stdout
sys.stdout = io.BytesIO()
yield
sys.stdout = save_stdout

once you have defined this context, for any block in which you don't want a stdout,

with nostdout():
foo()

More optimization: you just need to replace sys.stdout with an object that has a no-op write method. For example:

import contextlib
import sys

class DummyFile(object):
def write(self, x): pass

@contextlib.contextmanager
def nostdout():
save_stdout = sys.stdout
sys.stdout = DummyFile()
yield
sys.stdout = save_stdout

to be used the same way as the previous implementation of nostdout. I don't think it gets any cleaner or faster than this;-).

Suppressing output of module calling outside library

Open /dev/null for writing, use os.dup() to copy stdout, and use os.dup2() to copy your open /dev/null to stdout. Use os.dup2() to copy your copied stdout back to the real stdout after.

devnull = open('/dev/null', 'w')
oldstdout_fno = os.dup(sys.stdout.fileno())
os.dup2(devnull.fileno(), 1)
makesomenoise()
os.dup2(oldstdout_fno, 1)

How to suppress output of a series of plots

It looks like you are asking to suppress plots while in the Jupyter environment. The %matplotlib inline causes the plots to be rendered on the output. If you remove that line, you will not get the plot rendered and you'll get back the plot object (I tested this on your code).

You can't comment out %matplotlib inline once the kernel in Jupyter has run it - it persists within the kernel. You need to comment it out and restart the kernel, at which point I think you'll see the behavior you want.

Once you've modified the plots as you with, you can turn %matplotlib inline back on and render your updated plots.

If you need to turn %matplotlib inline on and off, you need to know a little about your Jupyter environment. Please see this answer

UPDATE:

I tried a few cases. It looks best if you explicitly set %matplotlib to an option other than inline. Here is minimal code to illustrate. I have kept all of your graphics-related code and made up data where your question does not provide values, and print the type for fig (which is your return value). I have also explicitly set %matplotlib notebook. Note that you should run %matplotlib --list to make sure that is one of your choices.

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.ticker as ticker

df = pd.DataFrame({'Close': [1,2,3], 'Volume': [4,5,6]})

%matplotlib notebook
# matplotlib.rc_file_defaults() # We don't have your defaults file
ax1 = sns.set_style("darkgrid"); #"style must be one of white, dark, whitegrid, darkgrid, ticks"
fig, ax1 = plt.subplots(figsize=(5,2))
lineplot = sns.lineplot(data=df['Close'], sort = False, ax=ax1)
ax1.xaxis.set_major_formatter(ticker.EngFormatter())
lineplot.set_title("This is the Title")
ax2 = ax1.twinx()
ax2.grid(False)
sns.lineplot(data=df['Volume'], sort = False, ax=ax2, alpha=0.15)
print(type(fig))

suppressing print as stdout python

You want to shadow (or otherwise hide) the stdout temporarily. Something like this:

actualstdout = sys.stdout
sys.stdout = StringIO()
result = foobar()
sys.stdout = actualstdout
sys.stdout.write(str(result))
sys.stdout.flush()
sys.exit(0)

You need to assign something that is file-like to sys.stdout so that other methods can use it effectively. StringIO is a good candidate because it doesn't require disk access (it'll just collect in memory) and then is discarded.



Related Topics



Leave a reply



Submit