Hammerite
Hammerite

Reputation: 22340

Why do these print() calls appear to execute in the wrong order?

weird.py:

import sys

def f ():
    print('f', end = '')
    g()

def g ():
    1 / 0

try:
    f()
except:
    print('toplevel', file = sys.stderr)

Python session:

Python 3.4.2 (v3.4.2:ab2c023a9432, Oct  6 2014, 22:16:31) [MSC v.1600 64 bit (AM
D64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import weird
toplevel
f>>>

Why does "toplevel" print before "f"?

This doesn't happen if the end = '' or the file = sys.stderr are removed.

Upvotes: 3

Views: 498

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121864

Because stdout and stderr are line buffered. They buffer characters and only flush when you have a complete line.

By setting end='' you ensure there is no complete line and the buffer isn't flushed until later when the Python interactive interpreter outputs >>> and flushes the buffer explicitly.

If you remove file=sys.stderr you output to sys.stdout again, and you printed toplevel\n as print() adds a newline, thus flushing the sys.stdout buffer.

You can explicitly force a flush by setting the flush=True argument to the print() function (Python 3.3 and up) or by calling sys.stdout.flush().

Upvotes: 7

Related Questions