开场白
如果你写的代码里面有一个很耗时的操作,比如这个10000*10000的操作,那么在执行的时候,很可能让你陷入未知的等待……
这时候,白银选手会直接加入一个print,但直接输出会让你的控制台直接爆炸。
黄金选手会加入\r,让输出保持在同一行。
当然,这样是静态的,继续加个刷新和延时,这样他就变成动态的了。
钻石选手甚至可以给你手搓一个进度条出来。(这里简化了一下算法,简化为遍历1-1000)
import time
total = 1000
interval = 20 # 每次更新的间隔数
for i in range(1, total + 1):
time.sleep(0.01) # 线程推迟指定时间运行,0.01秒代表休眠10毫秒
percentage = (i / total) * 100
num = int(percentage // 2)
if i == total:
process = "\r[%3.0f%%]: |%-50s|\n" % (percentage, '#' * num)
else:
process = "\r[%3.0f%%]: |%-50s|" % (percentage, '#' * num)
print(process, end='', flush=True)
但真正的王者,会使用现成的库!
正戏
progress
progress是一个简单的第三方进度条模块,只需要在代码中创建一个Bar对象,设置好长度,并在循环中更新他,就可以轻松得到一个进度条。(不知道为什么pycharm不显示进度条,下面的例子用的Thonny)
from progress.bar import Bar
import time
start = 1
end = 1000
with Bar('Processing', max=end) as bar:
for i in range(start, end + 1):
bar.next()
time.sleep(0.01) # 模拟处理时间
print("\n遍历完成!")
progress模块提供了多种进度条样式。
from progress.bar import Bar, ChargingBar, FillingSquaresBar, FillingCirclesBar, IncrementalBar, PixelBar, ShadyBar
from progress.spinner import Spinner, PieSpinner, MoonSpinner, LineSpinner, PixelSpinner
from progress.counter import Counter, Countdown, Stack, Pie
import time
import random
# 创建一个进度条和指示器的列表
progress_list = [
Bar, ChargingBar, FillingSquaresBar, FillingCirclesBar, IncrementalBar,
PixelBar, ShadyBar, Spinner, PieSpinner, MoonSpinner, LineSpinner,
PixelSpinner, Counter, Countdown, Stack, Pie
]
# 循环演示每个进度条和指示器
for P in progress_list:
# 使用P类创建一个进度条/指示器实例
progress_instance = P(P.__name__ + ':')
# 使用iter方法遍历范围
for i in progress_instance.iter(range(100)):
time.sleep(0.01)
# 随机进度条示例
bar = IncrementalBar('Random:', suffix='%(index)d%%')
for i in range(100):
bar.goto(random.randint(0, 100))
time.sleep(0.01)
bar.finish()
同时也可以通过修改参数修改进度条的填充字符和描述文本。
from progress.bar import Bar
import time
class CustomBar(Bar):
# 自定义进度条样式,使用篮球图标作为填充字符
fill = '🏀'
suffix = '%(percent).1f%% - %(eta)ds'
x = 1000
start = 0
end = x
# 使用自定义的进度条类
with CustomBar('剩余练习时长', max=end-start) as bar:
for i in range(start, end + 1):
bar.next()
time.sleep(0.01) # 模拟处理时间
print("\n遍历完成!")
tqdm
更加为人所熟知的进度条模块是tdqm。
(这个词据说是阿拉伯语“进度”的意思,也是西班牙语“我好爱你”的缩写。)
tqdm的使用更简单,只要给循环的迭代对象加上tqdm就行。
from tqdm import tqdm
x = 1000
for i in tqdm(range(1, x)):
pass
print('\n完成')
或者直接使用trange替代原有的range,都不用你在循环中增加代码。
from tqdm import trange
x = 1000
for i in trange(1, x):
pass
print('\n完成')
tqdm没搞花里胡哨的样式,但对各种开发环境的支持很好。
比如加上rich,你就可以得到一个彩色的进度条。
from tqdm.rich import trange
x = 1000
for i in trange(1, x):
pass
print('\n完成')
加上tk,则是一个基于tkinter的进度条。
from tqdm.tk import trange
x = 100000000
for i in trange(1, x):
pass
print('\n完成')
那么有人就要问了:
路人甲:我的进度条也不全是用在循环上啊!
那也简单,直接定义一个tqdm对象,然后在代码中手动更新
from tqdm.rich import tqdm
from time import sleep
bar=tqdm(total=100)
bar.set_description('采集数据')
sleep(0.5)
bar.update(10)
bar.set_description('清洗数据')
sleep(0.5)
bar.update(10)
bar.set_description('存储数据')
sleep(0.5)
bar.update(10)
bar.set_description('分析数据')
sleep(0.5)
bar.update(69)
bar.set_description('展示数据')
sleep(5)
bar.update(1)
bar.close()
print('完成!')
你现在知道为什么好多软件都卡在99%了吧!
alive-progress
如果你觉得tqdm不够彰显你代码独特的气质,那么你还可以试试alive-progress这个模块。他的写法类似前面的progress,看上去,平平无趣,但效果嘛~
from alive_progress.styles import showtime
showtime()
代码奉上,自己去试!