You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

rich Progress嵌套进度条时间显示异常问题求助

rich Progress嵌套进度条时间显示异常问题求助

问题描述

我尝试实现一个嵌套进度条,需要每次循环时重置内层任务的进度。目前的代码能正确显示进度,但时间部分有异常:

  • 内层任务task3的计时器在第一次循环时正常走动,但外层的task1task2的计时器一开始显示-:--:--(符合预期),但第二次迭代时直接显示0:00:00,没有累计内层任务的耗时
  • 所有任务完成后,时间会固定在0:00:00,不会更新为实际花费的总时间

我尝试过增加task1task2的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()方法,它会彻底重置任务的所有状态——包括completedstart_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

火山引擎 最新活动