0
from __future__ import print_function

import sys
from time import sleep

fp = sys.stdout
print('Do you want to continue (Y/n): ', end='')
# fp.flush()
sleep(5)

I don't know whether I am asking the right question. I have found many similar questions on StackOverflow but none of them were useful — They lacked details. Why does the print works after sleep is executed in this case? If I uncomment fp.flush() then print works first. Why is this happening even when print is present before sleep?

Niraj Raut
  • 205
  • 2
  • 7

2 Answers2

1

The underlying C libraries buffer stdout to reduce the number of system calls made during writes. If you run a program from a terminal, stdout is line buffered (it sends its data when it sees a newline). If you pipe stdout to another program or a file, it is block buffered and only sends data when some length such as 4096 bytes have been written. You can manually set stdout to RAW to stop buffering.

In your program, you print a message without a newline, so in either terminal or pipe mode, it is buffered in the local program. If you uncomment fd.flush()... that flushes the buffer into the operating system immediately. The sleep has no immediate effect on stdout. When the sleep ends, the file is flushed to the operating system and thus your screen when the program exits.

tdelaney
  • 73,364
  • 6
  • 83
  • 116
  • Hey, this may be a silly question. Let's say I have the following code: ```print('Input:', end=' ') input()``` In this case, shouldn't the input be taken first and then print since it didn't get a newline or is it forcibly flushed? – Niraj Raut May 03 '20 at 06:07
  • 2
    `input` is a helper that does `sys.stdout.write(msg);sys.stdout.flush();buf=sys.stdin.readline()`. In your case, print was buffered, `input` wrote an empty string then flushed. That's why you see the text on the screen. it wasn't the print, it was the input. You generally shouldn't do `print` then `input` as `input("something")` has the print builtin – tdelaney May 03 '20 at 06:14
0

The code quoted in the question demonstrates the effects of buffering.

First, the print works always.

By default all output is going to a buffer. This is an optimisation.

If you write/print to a terminal, the buffer is automatically flushed (i.e. data is sent to the device) when it contains a whole line, i.e. there is a newline character. Note that the print statement does not produce a newline, so the output does not appear on a screen as it usually does.

There are also other cases when the buffer is flushed: when it is full, when the file/device is closed, when the program exits (because all open descriptors are closed), when you request it with flush command. The program shows the effect of last two depending on how you comment or uncomment the statememts.

VPfB
  • 14,927
  • 6
  • 41
  • 75
  • Thanks! So, stdout is line-buffered, right? – Niraj Raut May 03 '20 at 05:24
  • 1
    Yes, it is. In general the options are: unbufferred, line buffered (default for terminals), block buffered (default for files). – VPfB May 03 '20 at 05:39
  • Hey, this may be a silly question. Let's say I have the following code: ```print('Input:', end=' ') input( )``` In this case, shouldn't the input run first and then print since it didn't get a newline or is it forcibly flushed? – Niraj Raut May 03 '20 at 05:47
  • 1
    @NirajRaut Good question. I think `input` almost certainly flushes the output even without the prompt argument, but did not verify that. – VPfB May 03 '20 at 06:07
  • Thanks! I was having a hard time understanding this. – Niraj Raut May 03 '20 at 06:11
  • 1
    I found the C source: https://github.com/python/cpython/blob/master/Python/bltinmodule.c and the flush command is there (currently line 2119): `tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush)` – VPfB May 03 '20 at 06:17
  • This isn't related to the question. When I write ```a = 1``` in python *a is a reference to an object of class int* — Correct me, if I am wrong. So, does the object of class int only contain the *value 1* or it contains other things as well? I searched about this but the answers didn't help me. – Niraj Raut May 04 '20 at 15:12