本文目录导读:

我来介绍几种在Python中实现进度条显示的方法,从简单到高级。
基础版本:使用 print 和 \r
import time
def simple_progress_bar(total=50):
"""简单的进度条实现"""
for i in range(total+1):
# 计算进度百分比
percent = i / total * 100
# 构建进度条显示
bar_length = 30
filled_length = int(bar_length * i / total)
bar = '█' * filled_length + '░' * (bar_length - filled_length)
# \r 回到行首,实现动态更新
print(f'\r进度: |{bar}| {percent:.1f}% ({i}/{total})', end='', flush=True)
time.sleep(0.1)
print() # 最后换行
# 运行示例
simple_progress_bar(50)
进阶版本:完整的进度条类
import time
import sys
class ProgressBar:
"""可重用的进度条类"""
def __init__(self, total=100, bar_length=40, prefix='进度'):
"""
初始化进度条
Args:
total: 总任务数
bar_length: 进度条长度
prefix: 前缀描述
"""
self.total = total
self.bar_length = bar_length
self.prefix = prefix
self.current = 0
def update(self, step=1):
"""更新进度"""
self.current += step
if self.current > self.total:
self.current = self.total
self._display()
def _display(self):
"""显示进度条"""
percent = self.current / self.total * 100
filled_length = int(self.bar_length * self.current / self.total)
bar = '█' * filled_length + '░' * (self.bar_length - filled_length)
sys.stdout.write(f'\r{self.prefix}: |{bar}| {percent:.1f}% ({self.current}/{self.total})')
sys.stdout.flush()
# 如果完成,换行
if self.current >= self.total:
print()
# 使用示例
def task_with_progress():
progress = ProgressBar(total=30, bar_length=30, prefix='下载中')
for i in range(30):
time.sleep(0.15) # 模拟耗时操作
progress.update(1)
task_with_progress()
使用 tqdm 库(推荐)
# 需要先安装: pip install tqdm
from tqdm import tqdm
import time
# 基本用法
def basic_tqdm():
# 在循环中使用
for i in tqdm(range(100), desc="处理中"):
time.sleep(0.05)
# 手动更新进度
def manual_tqdm():
pbar = tqdm(total=50, desc="下载文件")
for i in range(50):
time.sleep(0.1)
pbar.update(1) # 每步增加1
pbar.close()
# 嵌套进度条
def nested_tqdm():
for i in tqdm(range(5), desc="外层任务"):
for j in tqdm(range(20), desc=f"内层任务 {i}", leave=False):
time.sleep(0.05)
# 自定义格式
def custom_tqdm():
file_sizes = [1024, 2048, 512, 4096] # 文件大小(KB)
with tqdm(total=sum(file_sizes), unit='KB',
desc='下载进度', unit_scale=True) as pbar:
for size in file_sizes:
time.sleep(0.5) # 模拟下载
pbar.update(size) # 更新实际大小
# 运行示例
print("=== 基本用法 ===")
basic_tqdm()
print("\n=== 手动更新 ===")
manual_tqdm()
print("\n=== tqdm 美化示例 ===")
# 使用 tqdm 的一些高级特性
from tqdm import trange
# 类似于 range 但带进度条
for i in trange(50, desc="处理中", ncols=70):
time.sleep(0.1)
实际应用场景示例
import time
import random
from tqdm import tqdm
def simulate_file_download():
"""模拟文件下载"""
total_size = 1024 * 10 # 10MB
chunk_size = 64 # 每次64KB
print("开始下载文件...")
downloaded = 0
with tqdm(total=total_size, unit='KB',
unit_scale=True,
desc="下载进度",
bar_format='{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}]') as pbar:
while downloaded < total_size:
# 模拟下载一块数据
time.sleep(0.1)
chunk = random.randint(32, chunk_size)
downloaded += chunk
# 更新进度
pbar.update(chunk)
print("下载完成!")
def batch_process_with_progress():
"""批量处理文件"""
files = [f"file_{i}.txt" for i in range(20)]
results = []
for file in tqdm(files, desc="批量处理", unit="files"):
# 模拟处理文件
time.sleep(0.2)
# 模拟有时失败
if random.random() < 0.1:
tqdm.write(f"警告:处理 {file} 时出现问题")
results.append(f"processed_{file}")
return results
def download_with_eta():
"""带预计完成时间的下载"""
import requests
# 注意:这需要实际的网络请求,这里用模拟替代
total = 100
start_time = time.time()
pbar = tqdm(total=total, desc="下载中",
bar_format='{l_bar}{bar}| {percentage:3.0f}% [{elapsed}<{remaining}]')
for i in range(total):
time.sleep(0.1)
pbar.update(1)
# 自定义后处理显示
if i == 50:
pbar.set_description("超过一半了")
elif i == 80:
pbar.set_description("即将完成")
pbar.close()
print(f"总耗时: {time.time() - start_time:.2f}秒")
# 运行示例
print("=== 文件下载模拟 ===")
simulate_file_download()
print("\n=== 批量处理 ====")
results = batch_process_with_progress()
print(f"处理完成 {len(results)} 个文件")
print("\n=== 带有ETA ===")
download_with_eta()
自定义进度条的装饰器
import time
from functools import wraps
from tqdm import tqdm
def progress_bar(total=None, desc="处理中"):
"""进度条装饰器"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
# 获取 total 值
total_value = total
if total_value is None and 'total' in kwargs:
total_value = kwargs.pop('total')
if total_value:
with tqdm(total=total_value, desc=desc) as pbar:
kwargs['pbar'] = pbar
return func(*args, **kwargs)
else:
return func(*args, **kwargs)
return wrapper
return decorator
@progress_bar(desc="数据处理")
def process_data(total, pbar=None):
result = []
for i in range(total):
time.sleep(0.1)
result.append(i * 2)
if pbar:
pbar.update(1)
return result
# 使用装饰器
result = process_data(30)
print(f"处理完成,结果长度: {len(result)}")
选择建议
- 简单场景:使用基础版本的
print + \r - 需要更多功能:使用
tqdm库(最推荐) - 特定需求:自定义进度条类
tqdm 是 Python 社区最流行的进度条库,功能丰富、使用简单,建议在正式项目中使用。