11

Ok.. So probably an example is a good way to explain this problem

So I have something like this:

if __name__=="__main__"
    result = foobar()
    sys.stdout.write(str(result))
    sys.stdout.flush()
    sys.exit(0)

Now this script is being called from a ruby script.. and basically it parses the result there. But foobar() has a lot of print statments.. and stdout flushes all those prints as well. Is there a way (besides logging mathods) I can modify something over here which automatically suppresses those prints and just flushes this result?? Thanks

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
frazman
  • 32,081
  • 75
  • 184
  • 269

4 Answers4

18

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.

g.d.d.c
  • 46,865
  • 9
  • 101
  • 111
  • awesome.. just what i needed :) – frazman Mar 30 '12 at 20:04
  • 5
    What about using `sys.stdout = open(os.devnull,'w')` instead of `StringIO()`? – ovgolovin Mar 30 '12 at 20:07
  • @ovgolovin - definitely reasonable as well if there's no expectation you might ever need the output. With StringIO you could retrieve it if needed before you reset the original value of `stdout`. – g.d.d.c Mar 30 '12 at 20:09
  • 1
    If you're on Windows watch out for Windows bug - [Cannot redirect output when I run Python script on Windows using just script's name](http://stackoverflow.com/questions/3018848/). – Piotr Dobrogost Oct 04 '12 at 11:07
  • 2
    for anyone coming along like I did... don't try this inside an ipython console :) – Anentropic Mar 14 '13 at 19:52
  • @Anentropic What's the problem with the iPython console? – Dr_Zaszuś Apr 24 '18 at 09:01
  • @Dr_Zaszuś ha, I can't remember any more. I guess it blows up. I guess iPython needs real stdout to work properly. Probably if you isolated the lines above in a function it'd be ok. – Anentropic Apr 24 '18 at 09:09
8

With Python 3.4 and up you can use the redirect_stdout contextmanager like this:

with redirect_stdout(open(os.devnull, "w")):
    print("This text goes nowhere")
print("This text gets printed normally")
Felk
  • 7,720
  • 2
  • 35
  • 65
3
import sys

class output:
    def __init__(self):
        self.content = []
    def write(self, string):
        self.content.append(string)


if __name__=="__main__":

    out = output()                   
    sys.stdout = out                   #redirecting the output to a variable content

    result = foobar()
    sys.stdout.write(str(result))
    sys.stdout.flush() 

    sys.stdout = sys.__stdout__        #redirecting the output back to std output   
    print "o/p of foo :",out.content

    sys.exit(0)
Kristian Glass
  • 37,325
  • 7
  • 45
  • 73
1

This link shows how to redirect stdout in python. Redirect it to an internal pipe, then read your pipe and filter out the unwanted lines. That will let you keep only the lines you are interested in.

Community
  • 1
  • 1
Spencer Rathbun
  • 14,510
  • 6
  • 54
  • 73