当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当前回答
使用动态进度,最酷的进度条!
要以一种有用的方式使用任何进度条框架,即获得完成百分比和预计到达时间(ETA),您需要能够告诉您的处理将有多少步骤。
然后,您只需插入一个yield来标记一个项目已被处理,然后就可以开始了!
def compute():
for i in range(1000):
... # process items as usual.
yield # insert this :)
然后就像这样使用它:
from alive_progress import alive_bar
with alive_bar(1000) as bar:
for i in compute():
bar()
获得一个令人敬畏的和活着的进度条!
|█████████████▎ | ▅▃▁ 321/1000 [32%] in 8s (40.1/s, eta: 16s)
披露:我是alive-progress的作者,但它应该能很好地解决你的问题!阅读https://github.com/rsalmei/alive-progress上的文档了解更多信息。现在它也在木星笔记本!以下是它能做的更多例子:
其他回答
我想我有点晚了,但这应该适用于使用当前版本的python 3的人,因为这使用了“f-strings”,正如python 3.6 PEP 498中介绍的那样:
Code
from numpy import interp
class Progress:
def __init__(self, value, end, title='Downloading',buffer=20):
self.title = title
#when calling in a for loop it doesn't include the last number
self.end = end -1
self.buffer = buffer
self.value = value
self.progress()
def progress(self):
maped = int(interp(self.value, [0, self.end], [0, self.buffer]))
print(f'{self.title}: [{"#"*maped}{"-"*(self.buffer - maped)}]{self.value}/{self.end} {((self.value/self.end)*100):.2f}%', end='\r')
例子
#some loop that does perfroms a task
for x in range(21) #set to 21 to include until 20
Progress(x, 21)
输出
Downloading: [########------------] 8/20 40.00%
你可以使用tqdm:
from tqdm import tqdm
with tqdm(total=100, desc="Adding Users", bar_format="{l_bar}{bar} [ time left: {remaining} ]") as pbar:
for i in range(100):
time.sleep(3)
pbar.update(1)
在本例中,进度条运行了5分钟 它是这样显示的:
Adding Users: 3%|█████▊ [ time left: 04:51 ]
您可以随心所欲地更改它和自定义它。
这里有一个非常简单的版本,如果你有一个循环,只是想了解迭代的进展,比如每一个点,比如说,5000次迭代。
my_list = range(0,100000)
counter = 0
for x in my_list:
#your code here
counter = counter + 1
if counter % 5000 == 0:
print(".", end="") # end="" avoids a newline, keeps dots together
print() #this makes sure whatever you print next is in a new line
My_list不是方案的一部分。使用你自己的迭代对象,不管你在循环什么。 这个版本没有提前告诉您总共有多少次迭代。
我喜欢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%
这个进度条显示了每完成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%]
>>>