当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当前回答
对于类似的应用程序(在循环中跟踪进度),我简单地使用python-progressbar:
他们的例子是这样的,
from progressbar import * # just a simple progress bar
widgets = ['Test: ', Percentage(), ' ', Bar(marker='0',left='[',right=']'),
' ', ETA(), ' ', FileTransferSpeed()] #see docs for other options
pbar = ProgressBar(widgets=widgets, maxval=500)
pbar.start()
for i in range(100,500+1,50):
# here do something long at each iteration
pbar.update(i) #this adds a little symbol at each iteration
pbar.finish()
print
其他回答
一个简单的联机程序:
K = 628318
for k in range(K):
# your stuff
print(end="\r|%-80s|" % ("="*int(80*k/(K-1))))
|===================================================================== |
80是棒子的长度。最终,您需要一个最终的print()。
不要忘了数字进步指示器:
K = 628318
for k in range(K):
# your stuff
print(end="\r%6.2f %%" % (k/(K-1)*100))
94.53 %
如果需要,将两者结合起来并不难。
键是“回车”\r和打印中默认end=“\n”的抑制键。
有一些特定的库(比如这里的这个),但也许一些非常简单的库就可以做到:
import time
import sys
toolbar_width = 40
# setup toolbar
sys.stdout.write("[%s]" % (" " * toolbar_width))
sys.stdout.flush()
sys.stdout.write("\b" * (toolbar_width+1)) # return to start of line, after '['
for i in range(toolbar_width):
time.sleep(0.1) # do real work here
# update the bar
sys.stdout.write("-")
sys.stdout.flush()
sys.stdout.write("]\n") # this ends the progress bar
注意:progressbar2是progressbar的一个分支,已经很多年没有维护过了。
jelde015的一个更普通的答案(当然是他的功劳)
手动更新加载条将是:
import sys
from math import *
def loadingBar(i, N, size):
percent = float(i) / float(N)
sys.stdout.write("\r"
+ str(int(i)).rjust(3, '0')
+"/"
+str(int(N)).rjust(3, '0')
+ ' ['
+ '='*ceil(percent*size)
+ ' '*floor((1-percent)*size)
+ ']')
称之为:
loadingBar(7, 220, 40)
将结果:
007/220 [= ]
只要你想用当前的I值调用它。
将大小设置为条形图应有的字符数
上面的建议非常好,但我认为大多数人只是想要一个现成的解决方案,不依赖于外部包,但也是可重用的。
我得到了上面所有的优点,并把它做成了一个函数,以及一个测试用例。
要使用它,只需复制“def update_progress(progress)”下面的行,而不是测试脚本。不要忘记导入sys。在需要显示或更新进度条时调用此函数。
这是通过直接向控制台发送“\r”符号来将光标移回起始位置。python中的"print"不能识别上述符号,因此我们需要'sys'
import time, sys
# update_progress() : Displays or updates a console progress bar
## Accepts a float between 0 and 1. Any int will be converted to a float.
## A value under 0 represents a 'halt'.
## A value at 1 or bigger represents 100%
def update_progress(progress):
barLength = 10 # Modify this to change the length of the progress bar
status = ""
if isinstance(progress, int):
progress = float(progress)
if not isinstance(progress, float):
progress = 0
status = "error: progress var must be float\r\n"
if progress < 0:
progress = 0
status = "Halt...\r\n"
if progress >= 1:
progress = 1
status = "Done...\r\n"
block = int(round(barLength*progress))
text = "\rPercent: [{0}] {1}% {2}".format( "#"*block + "-"*(barLength-block), progress*100, status)
sys.stdout.write(text)
sys.stdout.flush()
# update_progress test script
print "progress : 'hello'"
update_progress("hello")
time.sleep(1)
print "progress : 3"
update_progress(3)
time.sleep(1)
print "progress : [23]"
update_progress([23])
time.sleep(1)
print ""
print "progress : -10"
update_progress(-10)
time.sleep(2)
print ""
print "progress : 10"
update_progress(10)
time.sleep(2)
print ""
print "progress : 0->1"
for i in range(101):
time.sleep(0.1)
update_progress(i/100.0)
print ""
print "Test completed"
time.sleep(10)
这是测试脚本显示的结果(最后一个进度条是动画):
progress : 'hello'
Percent: [----------] 0% error: progress var must be float
progress : 3
Percent: [##########] 100% Done...
progress : [23]
Percent: [----------] 0% error: progress var must be float
progress : -10
Percent: [----------] 0% Halt...
progress : 10
Percent: [##########] 100% Done...
progress : 0->1
Percent: [##########] 100% Done...
Test completed
#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