当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当前回答
#doesnt affect actual execution
#based on events and consumption in background
#may be that actual process completes a bit earlier than progress shows 99%
#make an instance with number of elements in a loop
#in each iteration call the method current_progress
import time
from math import ceil
import os
import sys
from threading import Thread
class progress_bar(object):
def __init__(self,total_elements,length_bar=25):
self.length_bar=length_bar
self.total_elements=total_elements
self.singleweight=(float(1)/float(total_elements))*100
self.done=0
self.qt=[0]
self.call_count=0
t=Thread(target=self.display_progress)
t.start()
def current_progress(self):
self.done+=1
self.qt=[self.done]+self.qt
def display_progress(self):
while True:
try:
done=self.qt.pop()
except:
continue
else:
self.call_count+=1
self.progress=self.singleweight*done
fill=ceil(self.progress)
bar=int((fill*self.length_bar)/100)*"|"
bar="["+bar+str(fill)+"%"
barp=bar
for i in range(0,self.length_bar+3-(len(bar))):
barp=barp+"_"
barp=barp+"]"
if self.progress <= 100:
os.system("clear")
print("Progress:",barp, sep=' ', end='\n', file=sys.stdout, flush=True)
if self.call_count == self.total_elements:
break
else:
pass
其他回答
我喜欢这一页。
从简单的示例开始,然后转移到多线程版本。开箱即用。不需要第三方软件包。
代码看起来像这样:
import time
import sys
def do_task():
time.sleep(1)
def example_1(n):
for i in range(n):
do_task()
print '\b.',
sys.stdout.flush()
print ' Done!'
print 'Starting ',
example_1(10)
或者这里是一个使用线程的例子,以便在程序运行时运行旋转加载条:
import sys
import time
import threading
class progress_bar_loading(threading.Thread):
def run(self):
global stop
global kill
print 'Loading.... ',
sys.stdout.flush()
i = 0
while stop != True:
if (i%4) == 0:
sys.stdout.write('\b/')
elif (i%4) == 1:
sys.stdout.write('\b-')
elif (i%4) == 2:
sys.stdout.write('\b\\')
elif (i%4) == 3:
sys.stdout.write('\b|')
sys.stdout.flush()
time.sleep(0.2)
i+=1
if kill == True:
print '\b\b\b\b ABORT!',
else:
print '\b\b done!',
kill = False
stop = False
p = progress_bar_loading()
p.start()
try:
#anything you want to run.
time.sleep(1)
stop = True
except KeyboardInterrupt or EOFError:
kill = True
stop = True
下面的代码是一个相当通用的解决方案,也有一个时间消耗和剩余时间估计。你可以使用任何可迭代对象。进度条的大小固定为25个字符,但可以使用完整、半块和四分之一块字符以1%的速度显示更新。输出如下所示:
18% |████▌ | \ [0:00:01, 0:00:06]
代码示例:
import sys, time
from numpy import linspace
def ProgressBar(iterObj):
def SecToStr(sec):
m, s = divmod(sec, 60)
h, m = divmod(m, 60)
return u'%d:%02d:%02d'%(h, m, s)
L = len(iterObj)
steps = {int(x):y for x,y in zip(linspace(0, L, min(100,L), endpoint=False),
linspace(0, 100, min(100,L), endpoint=False))}
qSteps = ['', u'\u258E', u'\u258C', u'\u258A'] # quarter and half block chars
startT = time.time()
timeStr = ' [0:00:00, -:--:--]'
activity = [' -',' \\',' |',' /']
for nn,item in enumerate(iterObj):
if nn in steps:
done = u'\u2588'*int(steps[nn]/4.0)+qSteps[int(steps[nn]%4)]
todo = ' '*(25-len(done))
barStr = u'%4d%% |%s%s|'%(steps[nn], done, todo)
if nn>0:
endT = time.time()
timeStr = ' [%s, %s]'%(SecToStr(endT-startT),
SecToStr((endT-startT)*(L/float(nn)-1)))
sys.stdout.write('\r'+barStr+activity[nn%4]+timeStr); sys.stdout.flush()
yield item
barStr = u'%4d%% |%s|'%(100, u'\u2588'*25)
timeStr = ' [%s, 0:00:00]\n'%(SecToStr(time.time()-startT))
sys.stdout.write('\r'+barStr+timeStr); sys.stdout.flush()
# Example
s = ''
for c in ProgressBar(list('Disassemble and reassemble this string')):
time.sleep(0.2)
s += c
print(s)
欢迎提出改进建议或其他意见。干杯!
它在我的程序中工作得很好。此外,我们需要添加一个计数器来指示循环时间。这个计数器作为方法update的参数。 例如:读取测试文件的所有行,并对它们进行处理。假设函数dosth()与变量i无关。
lines = open(sys.argv[1]).readlines()
i = 0
widgets=[Percentage(), Bar()]
pbar = ProgressBar(widgets=widgets,maxval=len(lines)).start()
pbar.start()
for line in lines:<pre>
dosth();
i += 1
pbar.update(i)</pre>
pbar.finish()
变量i通过方法update控制pbar的状态
您应该将进度条链接到手头的任务(以便它度量进度:D)。例如,如果您正在对一个文件进行ftp传输,您可以告诉ftplib获取一个特定大小的缓冲区,比如128K,然后您将128K所代表的文件大小的百分比添加到进度条中。如果您正在使用CLI,并且进度表有20个字符长,那么当文件传输了1/20时,您将添加一个字符。
这里有一个简单的解决方案!
void = '-'
fill = '#'
count = 100/length
increaseCount = 0
for i in range(length):
print('['+(fill*i)+(void*(length-i))+'] '+str(int(increaseCount))+'%',end='\r')
increaseCount += count
time.sleep(0.1)
print('['+(fill*(i+1))+(void*(length-(i+1)))+'] '+str(int(increaseCount))+'%',end='\n')
注意:如果需要,可以修改fill和“void”字符。
加载条(图片)