首页 > 解决方案 > 终端上进度条中的Python多线程异常输出

问题描述

我正在尝试在我的代码中实现进度条。但看起来由于某种原因,先前进度状态的最后一个元素没有被覆盖。有人可以解释为什么会这样吗?谢谢。

threadLock = threading.Lock()
count = 0

def mail(email_no):
    # Some code
    with threadLock:
        global count
        count+=1
        print('{} {}% completed. total sent={}'.format( chr(9608)*int((count/email_no)*100) ,((count/email_no)*100), count ), end ='\r' )


    # server.quit()

email_no = 1008
for i in range(1, email_no+1):
    t = Thread(target=mail, args=[email_no])
    t.start() 

它给了我以下输出:

████████████████████████████████████████████████████████████████████████████████ 100.0% completed. total sent=1008l sent=1007

为什么这total sent=1008l sent=1007是来而不是总发送= 1008?

标签: pythonmultithreading

解决方案


以下假设 Python 3。

问题是最后一行比它之前的行短。这是len("{}".format((1007/1008)*100))由 17 和len("{}".format((1008/1008.)*100))5 引起的。差异是 10,这也是不需要的后缀 的长度l sent=1007

解决此问题的一种方法是跟踪打印的最后一行的长度,然后用空格将该行填充到该长度。另一种选择是只填充每一行打印的line.ljust(os.get_terminal_size().columns).

import threading
from threading import Thread

threadLock = threading.Lock()
count = 0
last_line_length = 0

def mail(email_no):
    # Some code
    with threadLock:
        global count, last_line_length
        count+=1
        line = '{} {}% completed. total sent={}'.format( chr(9608)*int((count/email_no)*100) ,((count/email_no)*100), count ).ljust(last_line_length)
        print(line, end ='\r' )
        last_line_length = len(line)


    # server.quit()

email_no = 1008
for i in range(1, email_no+1):
    t = Thread(target=mail, args=[email_no])
    t.start() 

推荐阅读