当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当前回答
上面的建议非常好,但我认为大多数人只是想要一个现成的解决方案,不依赖于外部包,但也是可重用的。
我得到了上面所有的优点,并把它做成了一个函数,以及一个测试用例。
要使用它,只需复制“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
其他回答
如果它是一个大循环,迭代次数固定,需要花费很多时间,你可以使用我做的这个函数。循环的每一次迭代都增加了进展。其中count是循环的当前迭代,total是循环的值,size(int)是你想要的条的大小,以10为增量,即(size 1 =10个字符,size 2 =20个字符)
import sys
def loadingBar(count,total,size):
percent = float(count)/float(total)*100
sys.stdout.write("\r" + str(int(count)).rjust(3,'0')+"/"+str(int(total)).rjust(3,'0') + ' [' + '='*int(percent/10)*size + ' '*(10-int(percent/10))*size + ']')
例子:
for i in range(0,100):
loadingBar(i,100,2)
#do some code
输出:
i = 50
>> 050/100 [========== ]
你也可以用启迪。主要的优点是你可以在不覆盖进度条的同时记录日志。
import time
import enlighten
manager = enlighten.Manager()
pbar = manager.counter(total=100)
for num in range(1, 101):
time.sleep(0.05)
print('Step %d complete' % num)
pbar.update()
它还可以处理多个进度条。
import time
import enlighten
manager = enlighten.Manager()
odds = manager.counter(total=50)
evens = manager.counter(total=50)
for num in range(1, 101):
time.sleep(0.05)
if num % 2:
odds.update()
else:
evens.update()
对于类似的应用程序(在循环中跟踪进度),我简单地使用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
这里有一个简单的解决方案!
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”字符。
加载条(图片)
已经有很多令人惊叹的答案,但我想分享我对进度条的解决方案。
from time import sleep
def progress_bar(progress: float, total: float, width: int = 25):
percent = width * ((progress + 1) / total)
bar = chr(9608) * int(percent) + "-" * (width - int(percent))
print(f"\r|{bar}| {(100/width)*percent:.2f}%", end="\r")
numbers = range(0, 1000)
numbersLen = len(numbers)
for i in numbers:
sleep(0.01) # Do something usefull here
progress_bar(i, numbersLen)
编辑:
如果你正在寻找一个条,调整它是基于终端的宽度和可能的消息在结束,然后这也是工作。请注意,如果终端太窄,消息将消失,因为如果它太宽,竖条将断开。
def progressBar(progress: float, total: float, message: str = ""):
terminalWidth = get_terminal_size().columns
width = int(terminalWidth / 4)
percent = width * ((progress + 1) / total)
bar = chr(9608) * int(percent) + "-" * (width - int(percent))
if terminalWidth <= 40:
message = ""
else:
message = message + (" " * (int(terminalWidth / 2) - len(message)))
print(f"\r|{bar}| {(100/width)*percent:.2f}% " + message, end="\r")