pythonstdoutinteractive-mode

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


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?


Solution

  • 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)