sys.stdout.write() Acting different in interactive mode

472 views Asked by At

I have the code :

import sys
import time

for i in range(10):
    sys.stdout.write("\r Loading: {}".format(i))
    sys.stdout.flush()
    time.sleep(0.5)

which works perfectly when I run python3 dynamic_print.py, but when I fire the up the interactive interpreter by typing python3 and copy and run the above code into it, I get the output :

 Loading: 012
 Loading: 112
 Loading: 212
 Loading: 312
 Loading: 412
 Loading: 512
 Loading: 612
 Loading: 712
 Loading: 812
 Loading: 912

The last two digits 12, are updated every time I run it (it was 11 when I ran it the last time). Why does it act differently and how to mitigate this?

2

There are 2 answers

0
Sam Mason On BEST ANSWER

12 is the return value of write, i.e. the number of characters written. which in interactive mode is printed out, followed by a line feed

to fix this you could either indicate to the interpreter that you're not interested in this value (e.g. using _ = stdout.write(s)) or you could put everything into a function and hence keep it away from the REPL

I'd suggest doing the latter, e.g. something like:

def looper(n):
    for i in range(n):
        sys.stdout.write("\r Loading: {}".format(i))
        sys.stdout.flush()
        time.sleep(0.5)
    sys.stdout.write("\n")

then invoke as looper(10)

0
HARDY8118 On

First of all you are getting different outputs because when you run python3 dynamic_print python compiles your file and generates bytecode for your python code (.pyc) then executes it in a python runtime.

When you use python3 on console it interprets the commands as you enter them. So you cannot clear the output generated in the python console just by . That's why you are getting the output each time in new line.

Another thing to note is the difference between the python3 print() and sys.stdout.write() is the return type each of them has. print() returns none and sys.stdout.write returns the length of string. Refer to this answer. The return type is the reason for getting extra 12.