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?

petrichor
  • 6,459
  • 4
  • 36
  • 48
  • It works normally for me. – tckmn Jun 27 '13 at 12:54
  • Using CPython it behaves as expected. For both Linux and Windows. – Elazar Jun 27 '13 at 12:55
  • I'm using Canopy 1.0.1. It has Python 2.7.3 64 bit in it. – petrichor Jun 27 '13 at 12:56
  • 1
    I'm using CPython 2.6.5 on Linux and it behaves as expected. – ajwood Jun 27 '13 at 12:58
  • Sounds like it incorrectly somehow alternates the order of the new line and flushes... something like `print '\n', i, ; stdout.flush(); print time.time()` – Elazar Jun 27 '13 at 12:59
  • 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`? – Stefan Jun 27 '13 at 13:05
  • Works fine in `IPython 0.13.2` too.(linux: py 2.7.4) – Ashwini Chaudhary Jun 27 '13 at 13:19
  • 2
    @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. – Aya Jun 27 '13 at 13:25

1 Answers1

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()
Aya
  • 39,884
  • 6
  • 55
  • 55
  • 4
    But, `print` adds the new line automatically, so it should have been flushed anyway. – Elazar Jun 27 '13 at 12:56
  • 1
    @Elazar In CPython, perhaps. Maybe IPython behaves differently. – Aya Jun 27 '13 at 12:58
  • @Aya I think this behavior is built into libc. – Elazar Jun 27 '13 at 13:01
  • 3
    @Elazar It's a [bit more complicated than that](http://stackoverflow.com/questions/1716296/why-does-printf-not-flush-after-the-call-unless-a-newline-is-in-the-format-strin), so it'll depend on whether `sys.stdout.isatty()`. It's also worth noting that `python` has a `-u` option to use unbuffered stdout. – Aya Jun 27 '13 at 13:16