简体   繁体   中英

Sys.stdout.write not working as expected

I've got a test script that iterates through two string arrays, and I want to use sys.stdout.write to provide the user a simple 'progress bar'.

My current script:

import sys
from time import sleep
names  = ['Serv1', 'Serv2', 'Serv3', 'Serv4', 'Serv5']
states = ['Running', 'Stopped', 'Running', 'Running', 'Stopped']
terminated=0
passed=0
for i in range (0, len(names)):
    if 'Running' in states[i]:
        print " [*] stop if running {0} ".format(str(names[i]))
        #service_info(action, machine, names[i])
        terminated+=1
    else:
        print " [!] Passing over {0} ".format(str(names[i]))
        passed+=1
    sleep(2)
    sys.stdout.write(" [ ] {0}/{1} progress left\r".format(i+1, len(names)))

The expected output is for the sys.stdout.write to keep updating, whilst the print statements are informing the user of some action. But when I run this, the only time sys.stdout.write is shown is at the end of the script. Eg

 [*] stop if running Serv1
 [!] Passing over Serv2
 [*] stop if running Serv3
 [*] stop if running Serv4
 [!] Passing over Serv5
 [ ] 5/5 progress left

How can I get the progress left to be shown below all of the prints whilst updating?

You'll need to flush the buffer; all output is buffered; kept in memory until a certain amount of data has been collected, to improve write performance.

The print statement flushes that buffer for you, but when writing to stdout directly, you need to explicitly flush:

sys.stdout.write(" [ ] {0}/{1} progress left\r".format(i+1, len(names)))
sys.stdout.flush()

Next, you are writing to stdout after sleeping ; the very next thing you do is replace that line with the next print statement. Write the message before sleeping:

for i in range (0, len(names)):
    if 'Running' in states[i]:
        print " [*] stop if running {0} ".format(str(names[i]))
        #service_info(action, machine, names[i])
        terminated+=1
    else:
        print " [!] Passing over {0} ".format(str(names[i]))
        passed+=1
    sys.stdout.write(" [ ] {0}/{1} progress left\r".format(i+1, len(names)))
    sys.stdout.flush()
    sleep(2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM