5

My first time, so be gentle!

Using Python 3.4, on Win 7, I noted that time.sleep() hangs unexpectedly. I searched, but the related questions I found did not address my issue. The following code works as expected:

from time import sleep

def am_i_running():
    while True:
        print('starting test')
        sleep(0.5)
        print(".", end="")

if __name__ == '__main__':
    am_i_running()

It prints 'starting' test, then an infinite sequence of '.starting test' lines. But if I move the 'starting' message so that I have:

from time import sleep

def am_i_running():
    while True:
        sleep(0.5)
        print(".", end="")

if __name__ == '__main__':
    print('starting test')
    am_i_running()

This prints 'starting test' and then hangs forever -- but only when run as a script. If I import the module into Idle and invoke 'am_i_running()', it woks fine. Also, if I omit the 'starting test' output entirely, it works fine from the command line, too. The issue appears to be with the location of the print statement, rather than with time.sleep itself.

I'm guessing that this is a feature, rather than a bug; but I'm not understanding it. Hopefully, someone here can enlighten me.

1 Answers1

2

Output is buffered and will not be shown until the end of the line. Since your print(".", end="") doesn't include a linebreak at the end, it never flushes the buffer. It's not because you have a print before the sleep; the issue is that in your first example, a linebreak is printed on every loop iteration, but in your second example, no linebreaks are printed after the startup message.

You can see other questions about this. This one gives a simple answer:

import sys
sys.stdout.flush()
Community
  • 1
  • 1
BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • Thanks for the reply. I hadn't considered the buffering implications; and I can see that the solution works. However, I'm still confused as to why the problematic version of the code snippet works fine when invoked from within Idle (or from within the shell). There is a disconnect between importing the function and calling the function from a script. – user3763469 Jun 21 '14 at 20:35
  • 1
    @user3763469: The shell and/or IDLE may have turned off buffering. Some interactive shells do this because in an interactive setting unbuffered output often makes sense (it's interactive, so people want to see output as it happens). – BrenBarn Jun 21 '14 at 20:39