0

I'm using python 3 on Komodo, and I want for there to be a time delay between the execution of commands. However, using the code below, all of the print commands are launched at the same time, but it does show that the time after all the commands are executed is two seconds greater than the time before the commands are executed. Is there a way for the first line to be printed, wait a second, second line be printed, wait a second, and have third and fourth lines be print?

import time
from time import sleep

t=time.asctime(time.localtime(time.time()));
print(t)

time.sleep(1)

print('Good Night')

time.sleep(1)

print('I"m back')
t=time.asctime(time.localtime(time.time()));
print(t)
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • 2
    You are probably facing the output buffering. Check this out: https://stackoverflow.com/questions/107705/disable-output-buffering – Eugene Sh. Jun 05 '18 at 18:29
  • @EugeneSh. Unfortunately, that question is pretty 2.x-centric, and most of the answers are wrong or irrelevant for Python 3, so I think it may just confuse people. – abarnert Jun 05 '18 at 18:47
  • @EugeneSh. Then again, maybe we should close this one as a dup and add a proper 3.x answer and/or edit the top answer(s) on that one? – abarnert Jun 05 '18 at 18:48
  • @abarnert Maybe you are right. I am not a python expert, just identified a language-agnostic problem here. – Eugene Sh. Jun 05 '18 at 18:52
  • @EugeneSh. If it helps: Python 2's `stdout` is just a wrapper around the C stdio object; Python 3's `stdout` is a Python object that manually buffers and transcodes on top of the raw file descriptor. But meanwhile, you should have some insight into whether it makes more sense to keep this question separate, or merge them . – abarnert Jun 05 '18 at 18:53

1 Answers1

1

By default, print prints to sys.stdout, which is line-buffered when writing to an interactive terminal,1 but block-buffered when writing to a file.

So, when you run your code with python myscript.py from your Terminal or Command Prompt, you will see each line appear as it's printed, as desired.

But if you run it with, say, python myscript.py >outfile, nothing will get written until the buffer fills up (or until the script exits, if that never happens). Normally, that's fine. But apparently, however you're running your script in Komodo, it looks like a regular file, not an interactive terminal, to Python.


It's possible that you can fix that just by using or configuring Komodo differently.

I don't know much about Komodo, but I do see that there's an addon for embedding a terminal; maybe if you use that instead of sending output to the builtin JavaScript (?) console, things will work better, but I really have no idea.


Alternatively, you can make sure that the output buffer is flushed after each line by doing it manually, e.g., by passing the flush argument to print:

print(t, flush=True)

If you really want to, you can even replace print in your module with a function that always does this:

import builtins
import functools
print = functools.partial(builtins.print, flush=True)

… but you probably don't want to do that.


Alternatively, you can replace sys.stdout with a line-buffered file object over the raw stdout, just by calling open on its underlying raw file or file descriptor:

sys.stdout = open(sys.stdout.fileno(), buffering=1)

If you search around Stack Overflow or the web, you'll find a lot of suggestions to disable buffering. And you can force Python to use unbuffered output with the -u flag or the PYTHONUNBUFFERED environment variable. But that may not do any good in Python 3.2


1. As sys.stdout explains, it's just a regular text file, like those returned by open. As explained in open, this distinction is made by calling isatty.

2. Python 2's stdout is just a thin wrapper around the C stdio object, so if you open it unbuffered, there's no buffering. Python 3's stdout is a hefty wrapper around the raw file descriptor that does its own buffering and decoding (see the io docs for details), so -u will make sys.stdout.buffer.raw unbuffered, but sys.stdout itself will still be buffered, as explained in the -u docs.

abarnert
  • 354,177
  • 51
  • 601
  • 671