How to flush the printed statements in IPython
Asked Answered
E

1

7

I want to print some debug statements during a loop in my function and I use IPython to call the function. Let an example function be:

def test_print():
    import time
    for i in range(5):
        time.sleep(2)
        print i,  time.time()

The result is like follows:

0 1372337149.84
1 1372337151.84
2 1372337153.85
3 1372337155.85
4 1372337157.85

I expect each row to be printed, then wait for 2 seconds. But the behavior is as follows. I first observe:

0 1372337149.84
1 

Then, after 2 seconds I observe the time stamp of 1 and the id of the next row, which is 2. I observe the last time stamp finally. I couldn't figure out why it behaves like this instead of one row at a time. Any thoughts? Do I need a special flush function to print what is waiting to be printed?

Edomite answered 27/6, 2013 at 12:51 Comment(8)
It works normally for me.Bellicose
Using CPython it behaves as expected. For both Linux and Windows.Consider
I'm using Canopy 1.0.1. It has Python 2.7.3 64 bit in it.Edomite
I'm using CPython 2.6.5 on Linux and it behaves as expected.Naima
Sounds like it incorrectly somehow alternates the order of the new line and flushes... something like print '\n', i, ; stdout.flush(); print time.time()Consider
I think, I noticed similar behaviour with normal python when redirecting stdout to a file, some time ago. Does the flush maybe only occur, if there is no redirection, while ipython does a redirection from python's stdout to its own stdout?Affliction
Works fine in IPython 0.13.2 too.(linux: py 2.7.4)Erminiaerminie
@AshwiniChaudhary Probably depends on whether you run it from a CLI or a GUI. If it's run from a GUI, it'll probably redirect stdout to something other than a tty, which will make the stream fully buffered rather than line-buffered.Outlay
O
10

I've never used IPython, but it should suffice to flush stdout after each print statement.

Something like this ought to work...

def test_print():
    import time
    import sys
    for i in range(5):
        time.sleep(2)
        print i,  time.time()
        sys.stdout.flush()
Outlay answered 27/6, 2013 at 12:54 Comment(4)
But, print adds the new line automatically, so it should have been flushed anyway.Consider
@Consider In CPython, perhaps. Maybe IPython behaves differently.Outlay
@Outlay I think this behavior is built into libc.Consider
@Consider It's a bit more complicated than that, so it'll depend on whether sys.stdout.isatty(). It's also worth noting that python has a -u option to use unbuffered stdout.Outlay

© 2022 - 2024 — McMap. All rights reserved.