0%

Python进度条

前言

手动实现简单进度条 or tqdm 库实现进度条。


手动实现

基本想法,利用 \r 转义符将光标退回行首然后循环打印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import time

class ProgressBar:
""" 进度条 """
MAX_LENGTH = 25 # length of progress bar
STYLE_UNDO = '*' # show style of undo
STYLE_DONE = '=' # show syle of finish
def __init__(self, total=100, prefix="Loop"):
self.cur = 0
self.total = total
self.prefix = prefix

def restart(self, cur=None, total=None):
if cur is not None:
assert isinstance(cur, int), "Error type for cur: {}".format(cur)
self.cur = cur
if total is not None:
assert isinstance(total, int), "Error type for total: {}".format(total)
self.total = total

def step(self):
if self.cur >= self.total: return
self.cur += 1
undo = int(self.MAX_LENGTH * min(self.cur / self.total, 1))
print("\r{} [{}{}{}] {:>5.2f}%".format(self.prefix, self.STYLE_DONE * (max(1, undo) - 1), '>', self.STYLE_UNDO * (self.MAX_LENGTH - undo), self.cur / self.total * 100), end='')
if self.cur == self.total:
print()

使用方法

1
2
3
4
pb = ProgressBar(99)
for i in range(99):
pb.step()
time.sleep(0.02)

效果如下:

1
2
> Loop [===========>*************] 50.51%
> Loop [========================>] 100.00%

升级版

  1. 添加上下文管理器
  2. 添加可迭代对象

原代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class ProgressBar:
""" 进度条 """
MAX_LENGTH = 25 # length of progress bar
STYLE_UNDO = '*' # show style of undo
STYLE_DONE = '=' # show syle of finish
def __init__(self, total=100, prefix="Loop"):
self.cur = 0
self.total = total
self.prefix = prefix

def restart(self, cur=None, total=None):
if cur is not None:
assert isinstance(cur, int), "Error type for cur: {}".format(cur)
self.cur = cur
if total is not None:
assert isinstance(total, int), "Error type for total: {}".format(total)
self.total = total

def step(self):
if self.cur >= self.total: return
self.cur += 1
undo = int(self.MAX_LENGTH * min(self.cur / self.total, 1))
print("\r{} [{}{}{}] {:>5.2f}%".format(self.prefix, self.STYLE_DONE * (max(1, undo) - 1), '>', self.STYLE_UNDO * (self.MAX_LENGTH - undo), self.cur / self.total * 100), end='')
if self.cur == self.total:
print()

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
pass

def __call__(self, obj):
def f():
for o in obj:
self.step()
yield o
return f()

使用方法, 效果与前面相同

1
2
3
with ProgressBar(1000) as pb:
for i in pb(range(1000)):
time.sleep(0.02)

tqdm

tqdm 是专业的实现进度条的库

基本用法

基本的使用方法是将迭代器套上一个 tqdm 类即可

1
2
3
from tqdm import tqdm
for i in tqdm(range(10000)):
time.sleep(0.001)

等价于

1
2
3
from tqdm import trange
for i in trange(1000):
time.sleep(0.001)

类似对应 enumerate, zip, map 的有 tenumerate, tzip, tmap, 即前面加上 t

可以使用类似前面手动实现的上下文管理器的方式进行更新

1
2
3
4
with tqdm(total=87) as pbar:
for i in range(87):
time.sleep(0.1)
pbar.update(1)

注意在 Python 文件和在 Jupyter 中使用不同的方法会有不同的显示风格

  • Python: from tqdm import tqdm
  • Jupyter: from tqdm.notebook import tqdm
  • (新特性)自动判断: from tqdm.autonotebook import tqdm, trange

常用参数

  • desc: 加个前缀显示
  • color: 进度条颜色,可以是 rgb 值或颜色
  • total: 手动设置循环次数
  • leave: 设置为 Fasle 则加载完就消失掉

参考资料

--- ♥ end ♥ ---

欢迎关注我呀~