我们在写一些python程序时,如果程序运行时间较长,我们希望能够有一个进度条来动态的展示程序运行进度。
首先能想到的做法是用print将执行到第几步打印出来,但这样显然不是我们想要的进度条,显示进度占用了很多行,原因是print在末尾默认加上了”\n”换行符。详见《你应该知道的print》。
我们对进度条的需求:一是进度信息在一行中显示;二是每次都能够动态擦除一行中上一次的内容。那么很自然的想到print有没有相应的转义符,还真有这么一个,”\r”。
import time
N = 1000
for i in range(N):
print("进度:{0}%".format(round((i + 1) * 100 / N)), end="\r")
time.sleep(0.01)
输出格式:
100%
进度显示的问题解决了,有时候我们需要有一些时间方面的显示;例如已经耗费了多长时间,预计还剩下多少时间等。
import time
N = 1000
st = time.clock()
for i in range(N):
p = round((i + 1) * 100 / N)
duration = round(time.clock() - st, 2)
remaining = round(duration * 100 / (0.01 + p) - duration, 2)
print("进度:{0}%,已耗时:{1}s,预计剩余时间:{2}s".format(p, duration, remaining), end="\r")
time.sleep(0.01)
输出格式:进度:100%,已耗时:10s,预计剩余时间:10s
上面代码中计算remaining时p加上了0.01,是为了避免除0问题。
至此,控制台进度条可以工作了,但代码在不同地方使用时会比较冗余,理解了原理,可以封装成一个库。
实际上早就有人已经做好这个工作了,而且功能更加强大丰富。这里推荐progressbar,下载地址为https://pypi.python.org/pypi/progressbar2
- 简单用法1
import time
import progressbar
p = progressbar.ProgressBar()
N = 1000
for i in p(range(N)):
time.sleep(0.01)
- 简单用法2
import time
import progressbar
p = progressbar.ProgressBar()
N = 1000
p.start(N)
for i in range(N):
time.sleep(0.01)
p.update(i+1)
p.finish()
两种简单用法的输出格式都是:
100% (1000 of 1000) |#####################| Elapsed Time: 0:00:10 Time: 0:00:10
包含了百分百进度,数量进度,#号前进条,耗费时间,剩余时间。
- 高级点的用法(自己配置输出格式)
import time
import progressbar
bar = progressbar.ProgressBar(widgets=[
' [', progressbar.Timer(), '] ',
progressbar.Percentage(),
' (', progressbar.ETA(), ') ',
])
for i in bar(range(1000)):
time.sleep(0.01)
输出格式:
[Elapsed Time: 0:00:10] 100% (Time: 0:00:10)
主要方式有如下几种,可自由搭配:
'Timer', # 计时器
'ETA', # 预计剩余时间
'AbsoluteETA', # 预计结束的绝对时间,耗时很长时使用较方便
'Percentage', # 百分比进度,30%
'SimpleProgress', # 计数进度,300/1000
'Counter', # 单纯计数
'Bar' # “#”号进度条
例如:
import time
import progressbar
bar = progressbar.ProgressBar(widgets=[
progressbar.Percentage(),
' (', progressbar.SimpleProgress(), ') ',
' (', progressbar.AbsoluteETA(), ') ',])
for i in bar(range(1000)):
time.sleep(0.01)
输出示例:
54% ( 545 of 1000) (Estimated finish time: 2016-11-06 19:26:15)