当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当前回答
我真的很喜欢python-progressbar,因为它使用起来非常简单。
对于最简单的情况,它是:
import progressbar
import time
progress = progressbar.ProgressBar()
for i in progress(range(80)):
time.sleep(0.01)
外观可以自定义,它可以显示估计的剩余时间。举个例子,使用与上面相同的代码,但是包含:
progress = progressbar.ProgressBar(widgets=[progressbar.Bar('=', '[', ']'), ' ',
progressbar.Percentage(), ' ',
progressbar.ETA()])
其他回答
#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
下面是一个简短的解决方案,以编程方式构建加载条(您必须决定需要多长时间)。
import time
n = 33 # or however many loading slots you want to have
load = 0.01 # artificial loading time!
loading = '.' * n # for strings, * is the repeat operator
for i in range(n+1):
# this loop replaces each dot with a hash!
print('\r%s Loading at %3d percent!' % (loading, i*100/n), end='')
loading = loading[:i] + '#' + loading[i+1:]
time.sleep(load)
if i==n: print()
试试https://pypi.python.org/pypi/progress上的progress。
from progress.bar import Bar
bar = Bar('Processing', max=20)
for i in range(20):
# Do some work
bar.next()
bar.finish()
结果将是如下所示的条:
Processing |############# | 42/100
使用进度库!
pip install progress
下面是我编写的一个自定义子类,用于将ETA/流逝时间格式化为更好读的格式:
import datetime
from progress.bar import IncrementalBar
class ProgressBar(IncrementalBar):
'''
My custom progress bar that:
- Show %, count, elapsed, eta
- Time is shown in H:M:S format
'''
message = 'Progress'
suffix = '%(percent).1f%% (%(index)d/%(max)d) -- %(elapsed_min)s (eta: %(eta_min)s)'
def formatTime(self, seconds):
return str(datetime.timedelta(seconds=seconds))
@property
def elapsed_min(self):
return self.formatTime(self.elapsed)
@property
def eta_min(self):
return self.formatTime(self.eta)
if __name__=='__main__':
counter = 120
bar = ProgressBar('Processing', max=counter)
for i in range(counter):
bar.next()
time.sleep(1)
bar.finish()