背景介绍

在处理大量数据或执行耗时较长的操作时,用户往往需要了解程序的执行进度。通过在命令行中显示进度条,可以直观地展示任务的完成情况,提升用户体验。本文介绍如何使用Python的print函数实现一个简单而实用的命令行进度条。

实现原理

命令行进度条的核心原理是利用回车符\r实现同一行的刷新。当print函数中使用end=""参数时,可以防止自动换行,配合\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
28
29
30
31
32
33
import time

def display_progress_bar(current, total, bar_length=20):
"""
显示进度条

参数:
- current: 当前进度
- total: 总任务数
- bar_length: 进度条长度
"""
progress_percent = int(current / total * 100)
filled_length = int(bar_length * (progress_percent / 100))
bar = "|" + "-" * filled_length + " " * (bar_length - filled_length) + "|"
return f"\r正在处理: {bar} {progress_percent}% ({current}/{total})"

# 示例数组,实际应用中可替换为任何可迭代对象
data_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
num = len(data_array)

# 处理数组中的每个元素
for index, element in enumerate(data_array):
i = index + 1

# 模拟处理时间
time.sleep(0.3) # 实际应用中,这里是您的处理逻辑

# 每处理2个元素或处理到最后一个元素时更新进度条
if i % 2 == 0 or i == num:
print(display_progress_bar(i, num), end="")

# 处理完成后换行
print("\n处理完成!")

进阶用法

1. 添加处理速度和预估剩余时间

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
import time

def display_advanced_progress_bar(current, total, start_time, bar_length=20):
progress_percent = int(current / total * 100)
filled_length = int(bar_length * (progress_percent / 100))
bar = "|" + "-" * filled_length + " " * (bar_length - filled_length) + "|"

# 计算速度和剩余时间
elapsed_time = time.time() - start_time
if current == 0:
items_per_second = 0
eta = "未知"
else:
items_per_second = current / elapsed_time
eta_seconds = (total - current) / items_per_second if items_per_second > 0 else 0

# 格式化剩余时间
if eta_seconds < 60:
eta = f"{eta_seconds:.1f}秒"
elif eta_seconds < 3600:
eta = f"{eta_seconds/60:.1f}分钟"
else:
eta = f"{eta_seconds/3600:.1f}小时"

return f"\r进度: {bar} {progress_percent}% ({current}/{total}) 速度: {items_per_second:.2f}项/秒 剩余时间: {eta}"

# 使用示例
start_time = time.time()
data = list(range(100))

for i, _ in enumerate(data):
# 模拟处理
time.sleep(0.05)

# 更新进度条
if (i + 1) % 5 == 0 or i + 1 == len(data):
print(display_advanced_progress_bar(i + 1, len(data), start_time), end="")

print("\n处理完成!")

2. 使用tqdm库

对于更专业的进度条需求,可以使用tqdm库,它提供了更丰富的功能:

1
2
3
4
5
6
7
from tqdm import tqdm
import time

# 创建进度条
for item in tqdm(range(100), desc="处理进度"):
# 模拟处理
time.sleep(0.05)

应用场景

  1. 数据处理:处理大量数据时显示进度
  2. 文件操作:上传、下载或复制大文件时显示进度
  3. 批量任务:执行批量操作时显示完成情况
  4. 长时间计算:执行需要较长时间的计算任务时提供反馈

注意事项

  1. 进度条更新频率不宜过高,否则会影响性能
  2. 在多线程环境中使用时需要注意线程安全
  3. 在某些环境(如Jupyter Notebook)中,\r可能无法正常工作,需要使用其他方法
  4. 对于非常大的数据集,可以考虑按百分比而非按项目数更新进度条

通过合理使用进度条,可以显著提升命令行应用的用户体验,让用户清楚地了解程序执行情况。