9

I've got an extremely simple application:

import sys
from time import sleep

for i in range(3):
    sys.stdout.write('.')
    sleep(1)

print('Welcome!')

I expect it to print out a dot every second (3 times), after which it should display "Welcome!". Unfortunately, it simply waits three seconds, and then prints out everything at once. I'm on a mac running regular Python 2.7 and I have no clue why this code behaves like this. Any suggestions?

kramer65
  • 50,427
  • 120
  • 308
  • 488
  • possible duplicate of [Python output buffering](http://stackoverflow.com/questions/107705/python-output-buffering) – Bruce Jul 12 '13 at 08:44
  • See [this question](http://stackoverflow.com/questions/107705/python-output-buffering) for further details (and more advanced ways to do what you want). – abarnert Jul 12 '13 at 08:46

4 Answers4

14

It's because sys.stdout is buffered. Use flush:

import sys
from time import sleep

for i in range(3):
    sys.stdout.write('.')
    sys.stdout.flush()
    sleep(1)

print('Welcome!')
abarnert
  • 354,177
  • 51
  • 601
  • 671
zhangyangyu
  • 8,520
  • 2
  • 33
  • 43
6

You can call python with -u to make stdin, stdout, and stderr totally unbuffered. This would save you from having to manually flush them.

On Unix, call your script like python -u myscript.py

Or you can put it in the shebang: #!/usr/bin/python -u

ajwood
  • 18,227
  • 15
  • 61
  • 104
1

stdout is a buffered stream. The buffer is flushed implicitly when it reaches a newline character.

If you want to flush the buffer without writing a newline character, you must do so explicitly by calling sys.stdout.flush()

Another alternative is to write to stderr, which is not buffered.

Henrik
  • 4,254
  • 15
  • 28
0

You should use print or a logger.

If you want the behaviour you expect, you need to to use sys.flush to force the output.

Bruce
  • 7,094
  • 1
  • 25
  • 42