Python: why is this print automatically flushing to screen without flush()?

758 views Asked by At

I was reading about std.flush() in python. And I found this example a lot.

import sys,time
for i in range(10):
    print i,
    #sys.stdout.flush() 
    time.sleep(1)

It is often said that it makes a difference with/without the "sys.stdout.flush()". However, when I called this script from command prompt, it didn't make a difference in my case. Both printed numbers to the screen in real time. I used python 2.7.5 in windows.

Why is that happening?

p.s. In another example which printed the output through subprocess.PIPE instead of to the screen directly, I did observe a difference of the buffering.

What am I missing?

2

There are 2 answers

2
paxdiablo On BEST ANSWER

Using flush will generally guarantee that flushing is done but assuming the reverse relationship is a logical fallacy, akin to:

  1. Dogs are animals.
  2. This is an animal.
  3. Therefore this is a dog.

In other words, not using flush does not guarantee flushing will not happen.

Interestingly enough, using Python 2.7.8 under Cygwin in Win81, I see the opposite behaviour - everything is batched up until the end. It may be different with Windows-native Python, it may also be different from within IDLE.

1
ivan_pozdeev On

See stdio buffering. In brief:

Default Buffering modes:

  • stdin is always buffered
  • stderr is always unbuffered
  • if stdout is a terminal then buffering is automatically set to line buffered, else it is set to buffered

For me, the example you gave prints:

In cmd:

  • all the numbers upon exit in Cygwin's python
  • one by one in Win32 python

In mintty:

  • both all upon exit
  • both one by one with -u option
  • sys.stdout.isatty() returns False!

So, it looks like msvcrt's stdout is unbuffered when it points to a terminal. A test with a simple C program shows the same behaviour.