8

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
  • 45,059
  • 106
  • 285
  • 459
  • 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

13

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
  • 334,953
  • 41
  • 559
  • 636
zhangyangyu
  • 8,262
  • 2
  • 32
  • 43
5

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
  • 16,747
  • 15
  • 57
  • 98
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,204
  • 14
  • 27
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,044
  • 1
  • 24
  • 41