当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当前回答
回答没有外部库的简单进度条
import time, sys
def progress(size):
for item in range(size):
if(item==0):
print("[",end="")
elif(item==size-1):
print("]",end="\n")
else:
#main work goes here
time.sleep(0.1)
print("%",end="")
sys.stdout.flush()
progress(50)
其他回答
这个进度条显示了每完成2%的点和每完成10%的数字。
import sys
def ProgressBar (num, total, nextPercent, nextPoint):
num = float (num)
total = float (total) - 1
if not nextPoint:
nextPoint = 0.0
if not nextPercent:
nextPoint += 2.0
sys.stdout.write ("[0%")
nextPercent = 10
elif num == total:
sys.stdout.write ("100%]\n")
nextPercent += 10
elif not nextPoint:
nextPoint = 0.0
elif num / total * 100 >= nextPercent:
sys.stdout.write (str(int (nextPercent)) + "%")
nextPercent += 10
elif num / total * 100 >= nextPoint:
sys.stdout.write (":")
nextPoint += 2
return (nextPercent, nextPoint)
nextPercent, nextPoint = 0, 0
total = 1000
for num in range (total):
nextPercent, nextPoint = ProgressBar (num, total, nextPercent, nextPoint)
结果:
>>>
[0%::::10%:::::20%:::::30%:::::40%:::::50%:::::60%:::::70%:::::80%:::::90%:::::100%]
>>>
已经有很多令人惊叹的答案,但我想分享我对进度条的解决方案。
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")
在这里寻找等效的解决方案后,我只是为我的需求做了一个简单的进度类。我想我应该把它贴出来。
from __future__ import print_function
import sys
import re
class ProgressBar(object):
DEFAULT = 'Progress: %(bar)s %(percent)3d%%'
FULL = '%(bar)s %(current)d/%(total)d (%(percent)3d%%) %(remaining)d to go'
def __init__(self, total, width=40, fmt=DEFAULT, symbol='=',
output=sys.stderr):
assert len(symbol) == 1
self.total = total
self.width = width
self.symbol = symbol
self.output = output
self.fmt = re.sub(r'(?P<name>%\(.+?\))d',
r'\g<name>%dd' % len(str(total)), fmt)
self.current = 0
def __call__(self):
percent = self.current / float(self.total)
size = int(self.width * percent)
remaining = self.total - self.current
bar = '[' + self.symbol * size + ' ' * (self.width - size) + ']'
args = {
'total': self.total,
'bar': bar,
'current': self.current,
'percent': percent * 100,
'remaining': remaining
}
print('\r' + self.fmt % args, file=self.output, end='')
def done(self):
self.current = self.total
self()
print('', file=self.output)
例子:
from time import sleep
progress = ProgressBar(80, fmt=ProgressBar.FULL)
for x in xrange(progress.total):
progress.current += 1
progress()
sleep(0.1)
progress.done()
将打印以下内容:
[========] 17/80 (21%) 63
它在我的程序中工作得很好。此外,我们需要添加一个计数器来指示循环时间。这个计数器作为方法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的状态
我喜欢Brian Khuu的答案,因为它简单,不需要外部包。我做了一点改动,所以我在这里添加了我的版本:
import sys
import time
def updt(total, progress):
"""
Displays or updates a console progress bar.
Original source: https://stackoverflow.com/a/15860757/1391441
"""
barLength, status = 20, ""
progress = float(progress) / float(total)
if progress >= 1.:
progress, status = 1, "\r\n"
block = int(round(barLength * progress))
text = "\r[{}] {:.0f}% {}".format(
"#" * block + "-" * (barLength - block), round(progress * 100, 0),
status)
sys.stdout.write(text)
sys.stdout.flush()
runs = 300
for run_num in range(runs):
time.sleep(.1)
updt(runs, run_num + 1)
它取总运行次数(total)和目前处理的运行次数(progress),假设total >= progress。结果如下所示:
[#####---------------] 27%