rich Progress嵌套进度条时间显示异常问题求助
rich Progress嵌套进度条时间显示异常问题求助
问题描述
我尝试实现一个嵌套进度条,需要每次循环时重置内层任务的进度。目前的代码能正确显示进度,但时间部分有异常:
- 内层任务
task3的计时器在第一次循环时正常走动,但外层的task1和task2的计时器一开始显示-:--:--(符合预期),但第二次迭代时直接显示0:00:00,没有累计内层任务的耗时 - 所有任务完成后,时间会固定在
0:00:00,不会更新为实际花费的总时间
我尝试过增加task1和task2的total值,发现它们会开始计算预估时间,但第一次循环完成后时间还是会卡在0:00:00。
我的代码如下:
import time from rich.progress import Progress with Progress() as progress: task1 = progress.add_task("[red]Downloading...", total=2) task2 = progress.add_task("[green]Processing...", total=2) task3 = progress.add_task("[cyan]Cooking...", total=200) for i in range(2): progress.update(task2, completed=0) for j in range(2): progress.update(task3, completed=0) for k in range(200): progress.update(task3, advance=1) time.sleep(0.01) else: progress.update(task2, advance=1) else: progress.update(task1, advance=1)
运行后进度条显示示例:
Downloading... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 Processing... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 Cooking... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
我现在的疑问是:是不是我只重置了任务的completed计数,但没有重置计时器?如果是这样,应该怎么正确重置任务的时间状态呢?
解决方案
你猜的完全没错!问题的核心就是你只重置了任务的completed值,但没有重置任务的启动时间(start_time)。
rich的Progress组件的工作逻辑是这样的:当任务第一次被更新进度时,会自动记录一个start_time;当任务的completed达到total时,组件会标记该任务为“已完成”状态,后续再修改completed时,计时器不会重新启动,所以就出现了时间卡住或者不累计的情况。
解决这个问题最简单的方式是使用progress.reset()方法,它会彻底重置任务的所有状态——包括completed、start_time,甚至会把任务从“已完成”状态拉回到“待运行”状态,完美适配你的嵌套循环场景。
修改后的代码如下:
import time from rich.progress import Progress with Progress() as progress: task1 = progress.add_task("[red]Downloading...", total=2) task2 = progress.add_task("[green]Processing...", total=2) task3 = progress.add_task("[cyan]Cooking...", total=200) for i in range(2): # 重置task2的全部状态,包括计时器 progress.reset(task2) for j in range(2): # 重置task3的全部状态 progress.reset(task3) for k in range(200): progress.update(task3, advance=1) time.sleep(0.01) else: progress.update(task2, advance=1) else: progress.update(task1, advance=1)
如果你不想完全重置任务(比如想保留自定义的颜色、描述等设置),也可以手动更新start_time为当前时间,同时重置completed:
progress.update(task2, completed=0, start_time=time.time())
这样修改后,外层任务的计时器会正确累加每次内层循环的耗时,任务完成后也会显示实际花费的总时间,不会再卡在0:00:00了。
备注:内容来源于stack exchange,提问作者MaKaNu




