当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回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()
其他回答
如果它是一个大循环,迭代次数固定,需要花费很多时间,你可以使用我做的这个函数。循环的每一次迭代都增加了进展。其中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 [========== ]
它在我的程序中工作得很好。此外,我们需要添加一个计数器来指示循环时间。这个计数器作为方法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的状态
from IPython.display import clear_output
progress_bar=u"\u001b[7m Loading: "
for i in range(100):
clear_output(wait=True)
progress_bar+=u"\u001b[7m "
print(progress_bar+str(i+1)+"%")
time.sleep(0.03) #you can change the speed
输出
我喜欢加布里埃尔的答案,但我改变了它的灵活性。您可以将bar-length发送到函数,并获得您想要的任何长度的进度条。进度条的长度不能为零或负。同样,你也可以像Gabriel answer一样使用这个函数(请看例子#2)。
import sys
import time
def ProgressBar(Total, Progress, BarLength=20, ProgressIcon="#", BarIcon="-"):
try:
# You can't have a progress bar with zero or negative length.
if BarLength <1:
BarLength = 20
# Use status variable for going to the next line after progress completion.
Status = ""
# Calcuting progress between 0 and 1 for percentage.
Progress = float(Progress) / float(Total)
# Doing this conditions at final progressing.
if Progress >= 1.:
Progress = 1
Status = "\r\n" # Going to the next line
# Calculating how many places should be filled
Block = int(round(BarLength * Progress))
# Show this
Bar = "[{}] {:.0f}% {}".format(ProgressIcon * Block + BarIcon * (BarLength - Block), round(Progress * 100, 0), Status)
return Bar
except:
return "ERROR"
def ShowBar(Bar):
sys.stdout.write(Bar)
sys.stdout.flush()
if __name__ == '__main__':
print("This is a simple progress bar.\n")
# Example #1:
print('Example #1')
Runs = 10
for i in range(Runs + 1):
progressBar = "\rProgress: " + ProgressBar(10, i, Runs)
ShowBar(progressBar)
time.sleep(1)
# Example #2:
print('\nExample #2')
Runs = 10
for i in range(Runs + 1):
progressBar = "\rProgress: " + ProgressBar(10, i, 20, '|', '.')
ShowBar(progressBar)
time.sleep(1)
print('\nDone.')
# Example #2:
Runs = 10
for i in range(Runs + 1):
ProgressBar(10, i)
time.sleep(1)
结果:
这是一个简单的进度条。 示例# 1 进度:[###-------]30% 例# 2 进步 : [||||||||||||........) 60% 完成了。
已经有很多好的答案,但添加这个特定的基于@HandyGold75的答案,我希望它在特定的上下文中是callabe,有一个初始的msg,加上在结束时的几秒钟的时间反馈。
from time import sleep, time
class ProgressBar:
def __init__(self, total: float, width: int = 50, msg: str = ""):
self.total = total
self.width = width
self.start: float = time()
if msg:
print(f"{msg}")
def progress(self, progress: float):
percent = self.width * ((progress) / self.total)
bar = chr(9608) * int(percent) + "-" * (self.width - int(percent))
print(
f"\r|{bar}| {(100/self.width)*percent:.2f}% "
f"[{progress} of {self.total}]",
end="\r",
)
def __enter__(self):
return self.progress
def __exit__(self, type, value, traceback):
end: float = time()
print(f"\nFinished after {end - self.start: .3f} seconds.")
# USAGE
total_loops = 150
with ProgressBar(total=total_loops) as progress:
for i in range(total_loops):
sleep(0.01) # Do something usefull here
progress(i + 1)