python实现控制台进度条

对于开发或者运维来说,使用Python去完成一些跑批任务,或者做一些监控事件是非常正常的情况。那么如何有效地监控任务的进度?除了在任务中加上Log外,还能不能有另一种方式来了解任务进展到哪一步了呢?
这就是今天我们来了解的内容——进度条。

方案一

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
39
40
41
42
43
44
45
46
47
48
49
50
51
#========================================================
# 进度条
#========================================================

class process_bar(object):
'''
#号进度条
用法:
bar = process_bar()
total = 100
for i in range(total + 1):
print(bar(i, total), end='')
'''
def __init__(self, number=50, decimal=2):
'''
INPUT -> "#"号的个数, 保留的小数位
'''
self.decimal = decimal
self.number = number
self.a = 100/number # 在百分比 为几时增加一个 # 号

def __call__(self, now, total):
# 获取当前的百分比数
percentage = self.percentage_number(now, total)
# 计算"#"号个数
well_num = int(percentage / self.a)
# 字符进度条
progress_bar_num = self.progress_bar(well_num)
# 完成的进度条
result = "\r%s %s" % (progress_bar_num, percentage)
return result

def percentage_number(self, now, total):
'''
计算百分比
INPUT -> 现在的数, 总数
OUTPUT -> 百分比
'''
return round(now / total * 100, self.decimal)

def progress_bar(self, num):
'''
显示进度条位置
INPUT -> 拼接的"#"号的数量
OUTPUT -> 当前的进度条
'''
# "#" 号个数
well_num = "#" * num
# 空格的个数
space_num = " " * (self.number - num)
return '[%s%s]' % (well_num, space_num)

方案二

使用一个第三方库–progressbar

1
pip install progressbar

使用方法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import  time
from progressbar import *

total = 1000

def dosomework():
time.sleep(0.01)

widgets = ['Progress: ',Percentage(), ' ', Bar('#'),' ', Timer(),
' ', ETA(), ' ', FileTransferSpeed()]
pbar = ProgressBar(widgets=widgets, maxval=10*total).start()
for i in range(total):
# do something
pbar.update(10 * i + 1)
dosomework()
pbar.finish()

方案三

使用第三方库–tqdm

1
pip install tqdm

使用方法如下

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import tqdm
import random
import httpx
import time

#========================================================
# 案例一
#========================================================

def improve_guess(rt, n):
return (rt + n/rt) / 2

guess = 1
target = 2
for i in tqdm.trange(10000000):
guess = improve_guess(guess, target)

#========================================================
# 案例二
#========================================================

numbers = [random.uniform(0, 2.8) for i in range(1000000)]
result = 1
for num in tqdm.tqdm(numbers):
result *= num

#========================================================
# 案例三
#========================================================

url = 'https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz'

with httpx.stream('GET', url) as response:
total = int(response.headers['Content-Length'])
with tqdm.tqdm(total=total) as progress:
for chunk in response.iter_bytes():
progress.update(len(chunk))

#========================================================
# 案例四
#========================================================

files = [f'vid-{i}.mp4' for i in range(4)]
for fname in tqdm.tqdm(files, desc='files'):
total = random.randrange(10**9, 2 * 10**9)
with tqdm.tqdm(total=total, desc=fname) as progress:
current = 0
while current < total:
chunk_size = min(random.randrange(10**3, 10**5), total - current)
current += chunk_size
if random.uniform(0, 1) < 0.01:
time.sleep(0.1)
progress.update(chunk_size)