Typer进度条实现:使用rich库展示美观的进度指示

Typer进度条实现:使用rich库展示美观的进度指示

【免费下载链接】typer Typer是一款基于Python类型提示构建的库,用于轻松编写高质量命令行接口(CLI)程序。 【免费下载链接】typer 项目地址: https://gitcode.com/GitHub_Trending/ty/typer

在开发命令行工具时,长时间运行的操作往往会让用户感到不安——他们不知道程序是否在正常工作,也不知道还需要等待多久。Typer通过集成Rich库,为开发者提供了强大而美观的进度指示功能,让命令行界面变得更加友好和专业。

为什么选择Rich进度条?

Rich是Python生态中功能最强大的终端美化库之一,它提供了:

  • 🎨 丰富的视觉效果:彩色进度条、动态旋转器、实时更新
  • 高性能渲染:优化的终端输出,避免闪烁
  • 📊 多种显示模式:进度条、旋转器、多任务并行显示
  • 🔧 高度可定制:支持自定义标签、颜色、格式

基础进度条实现

使用Rich的track函数

最简单的进度条实现方式是利用Rich的track()函数:

import time
import typer
from rich.progress import track

def process_data():
    total = 0
    for value in track(range(100), description="处理中..."):
        # 模拟处理时间
        time.sleep(0.01)
        total += 1
    print(f"已处理 {total} 个项目")

if __name__ == "__main__":
    typer.run(process_data)

运行效果:

$ python app.py
处理中... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸━━━━━━━━━━ 74% 0:00:01
已处理 100 个项目

进度条配置选项

Rich的track函数支持多种配置参数:

参数类型说明默认值
descriptionstr进度条描述文字None
totalint总任务数len(iterable)
auto_refreshbool是否自动刷新True
consoleConsole控制台实例None
transientbool完成后是否清除False
get_timecallable时间获取函数time.monotonic
refresh_per_secondfloat刷新频率10

高级进度显示:多任务旋转器

当无法预知操作完成时间时,旋转器(Spinner)是更好的选择:

import time
import typer
from rich.progress import Progress, SpinnerColumn, TextColumn

def complex_operation():
    with Progress(
        SpinnerColumn(),
        TextColumn("[progress.description]{task.description}"),
        transient=True,
    ) as progress:
        task1 = progress.add_task(description="数据预处理...", total=None)
        task2 = progress.add_task(description="模型训练...", total=None)
        
        # 模拟多任务操作
        for i in range(5):
            time.sleep(1)
            if i < 3:
                progress.update(task1, advance=1)
            else:
                progress.update(task2, advance=1)
    
    print("所有操作已完成!")

if __name__ == "__main__":
    typer.run(complex_operation)

运行效果:

$ python app.py
⠹ 数据预处理...
⠹ 模型训练...
所有操作已完成!

Typer内置进度条功能

虽然推荐使用Rich,但Typer也提供了内置的进度条功能,基于Click的进度条实现:

基本用法

import time
import typer

def process_items():
    items = ["项目A", "项目B", "项目C", "项目D", "项目E"]
    
    with typer.progressbar(items, label="处理项目") as progress:
        for item in progress:
            # 模拟每个项目的处理时间
            time.sleep(0.5)
            # 这里可以添加实际的处理逻辑
    
    print("所有项目处理完成")

if __name__ == "__main__":
    typer.run(process_items)

手动控制进度

对于非迭代式的操作,可以手动控制进度更新:

import time
import typer

def batch_processing():
    total_records = 1000
    batch_size = 250
    
    with typer.progressbar(length=total_records, label="批量处理") as progress:
        for batch in range(4):
            # 模拟批处理操作
            time.sleep(1)
            # 手动更新进度
            progress.update(batch_size)
    
    print(f"已完成 {total_records} 条记录的处理")

if __name__ == "__main__":
    typer.run(batch_processing)

进度条最佳实践

1. 提供有意义的描述

# 好的实践
with typer.progressbar(data, label="解析用户数据") as progress:
    pass

# 不好的实践  
with typer.progressbar(data) as progress:
    pass

2. 处理异常情况

def safe_processing():
    try:
        with typer.progressbar(process_data(), length=100) as progress:
            for item in progress:
                process_item(item)
    except KeyboardInterrupt:
        print("\n操作已取消")
    except Exception as e:
        print(f"\n处理失败: {e}")

3. 组合使用Rich和Typer

import typer
from rich.progress import Progress, BarColumn, TimeRemainingColumn

app = typer.Typer()

@app.command()
def import_data(file_path: str):
    """导入数据文件"""
    with Progress(
        BarColumn(),
        "[progress.description]{task.description}",
        TimeRemainingColumn(),
    ) as progress:
        task = progress.add_task("导入数据", total=100)
        
        # 模拟导入过程
        for i in range(100):
            time.sleep(0.1)
            progress.update(task, advance=1)
    
    print("数据导入完成")

if __name__ == "__main__":
    app()

进度显示方案对比

下表对比了不同进度显示方案的适用场景:

方案适用场景优点缺点
Rich track()已知总量的迭代操作美观、功能丰富需要额外依赖
Rich Progress复杂多任务操作高度可定制、多任务配置较复杂
Typer进度条简单进度显示内置、无需额外依赖功能有限
手动输出极简单需求完全控制需要手动实现

实战案例:文件处理工具

下面是一个完整的文件处理工具示例,展示了进度条的实战应用:

import os
import time
import typer
from rich.progress import Progress, BarColumn, TextColumn
from pathlib import Path

app = typer.Typer()

def process_file(file_path: Path, progress, task_id):
    """处理单个文件"""
    # 模拟文件处理时间(基于文件大小)
    file_size = file_path.stat().st_size
    process_time = min(file_size / 1024 / 1024 * 0.1, 2.0)  # 最大2秒
    
    time.sleep(process_time)
    progress.update(task_id, advance=1)

@app.command()
def batch_process(directory: str, pattern: str = "*.txt"):
    """批量处理目录中的文件"""
    dir_path = Path(directory)
    files = list(dir_path.glob(pattern))
    
    if not files:
        print("未找到匹配的文件")
        return
    
    with Progress(
        BarColumn(),
        TextColumn("[progress.description]{task.description}"),
        TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
    ) as progress:
        task = progress.add_task("处理文件", total=len(files))
        
        for file_path in files:
            process_file(file_path, progress, task)
    
    print(f"已完成 {len(files)} 个文件的处理")

if __name__ == "__main__":
    app()

性能优化建议

  1. 合理设置刷新频率:避免过于频繁的进度更新影响性能
  2. 使用transient模式:完成后自动清除进度条,保持界面整洁
  3. 批量更新:对于大量小任务,可以累积一定数量后再更新进度
  4. 避免阻塞操作:确保进度更新不会阻塞主线程

总结

Typer结合Rich库提供了强大的进度显示能力,让命令行工具变得更加专业和用户友好。通过选择合适的进度显示方案,你可以:

  • ✅ 提升用户体验,减少等待焦虑
  • ✅ 展示专业的产品形象
  • ✅ 提供操作状态的实时反馈
  • ✅ 支持复杂的多任务进度显示

记住关键原则:对于简单需求使用Typer内置进度条,对于复杂场景优先选择Rich库。正确的进度显示不仅是一个技术实现,更是对用户体验的重视和尊重。

现在就开始为你的Typer应用添加精美的进度指示吧! 🚀

【免费下载链接】typer Typer是一款基于Python类型提示构建的库,用于轻松编写高质量命令行接口(CLI)程序。 【免费下载链接】typer 项目地址: https://gitcode.com/GitHub_Trending/ty/typer

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值