The issue
By default, output from a Python program is buffered to improve performance. The terminal is a separate program from your code, and it is more efficient to store up text and communicate it all at once, rather than separately asking the terminal program to display each symbol.
Since terminal programs are usually meant to be used interactively, with input and output progressing a line at a time (for example, the user is expected to hit Enter to indicate the end of a single input item), the default is to buffer the output a line at a time.
So, if no newline is print
ed, the print
function (in 3.x; print
statement in 2.x) will simply add text to the buffer, and nothing is displayed.
Outputting in other ways
Every now and then, someone will try to output from a Python program by using the standard output stream directly:
import sys
sys.stdout.write('test')
This will have the same problem: if the output does not end with a newline, it will sit in the buffer until it is flushed.
Fixing the issue
For a single print
We can explicitly flush the output after printing.
In 3.x, the print
function has a flush
keyword argument, which allows for solving the problem directly:
for _ in range(10):
print('.', end=' ', flush=True)
time.sleep(.2) # or other time-consuming work
In 2.x, the print
statement does not offer this functionality. Instead, flush the stream explicitly, using its .flush
method. The standard output stream (where text goes when print
ed, by default) is made available by the sys
standard library module, and is named stdout
. Thus, the code will look like:
for _ in range(10):
print '.',
sys.stdout.flush()
time.sleep(.2) # or other time-consuming work
For multiple print
s
Rather than flushing after every print
(or deciding which ones need flushing afterwards), it is possible to disable the output line buffering completely. There are many ways to do this, so please refer to the linked question.
sys.stdout.flush()
after you print. If that solves your issue, buffering is actually your problem. – Pustulantsys.stdout.write('.')
, notprint '.',
. First,print
will give you spaces between the dots. Second, it's theoretically allowed to do its own buffering on top of whateverstdout
does (although CPython doesn't, and I don't know of any implementation that does). – Latecomersys.stdout.write
is what I recommend as well. For a workaround (e.g. you can't modify the source code), you can try running Python with-u
as described here – Monocularcurses
-based Text UI framework like Urwid and draw a fancy progress bar. Urwid would then automatically take care of buffering / screen redrawing issues for you. But it's a lot more work and would add a significant dependency to your project. – Pustulant