tqdm:提取时间过去 + 剩余时间?

Coo*_*654 7 python printing iterable progress-bar tqdm

我一直在浏览 tqdm文档,但无论我在哪里看,我都找不到一种方法来提取经过的时间和估计的剩余时间字段(基本上是每行进度条的中心:)00:00<00:02

 0%|          | 0/200 [00:00<?, ?it/s]
  4%|?         | 7/200 [00:00<00:02, 68.64it/s]
  8%|?         | 16/200 [00:00<00:02, 72.87it/s]
 12%|??        | 25/200 [00:00<00:02, 77.15it/s]
 17%|??        | 34/200 [00:00<00:02, 79.79it/s]
 22%|???       | 43/200 [00:00<00:01, 79.91it/s]
 26%|???       | 52/200 [00:00<00:01, 80.23it/s]
 30%|???       | 61/200 [00:00<00:01, 82.13it/s]
....
100%|??????????| 200/200 [00:02<00:00, 81.22it/s]
Run Code Online (Sandbox Code Playgroud)

tqdm基本上通过在发生更新时打印动态进度条来工作,但是有没有办法“只”打印00:0100:02部分,所以我可以在我的 Python 程序的其他地方使用它们,例如在自动停止代码中,如果它停止进程花的时间太长了吗?

cas*_*dcl 12

tqdm对象通过公共属性公开一些信息format_dict

from tqdm import tqdm

with tqdm(total=100) as t:
    ...
    t.update()
    print(t.format_interval(t.format_dict['elapsed']))
Run Code Online (Sandbox Code Playgroud)

否则你可以解析 str(t).split()


Jos*_*pel -2

编辑:请参阅下面库维护者的答案。事实证明,可以在公共 API 中获取此信息。


tqdm不会将该信息作为其公共 API 的一部分公开,并且我不建议尝试破解您自己的信息。那么您将依赖于tqdm随时可能发生变化的实现细节。

但是,这不应该阻止您编写自己的。使用计时器来检测循环非常容易,如果循环时间太长,您可以中止循环。这是一个快速、粗略的示例,仍然用于tqdm提供视觉反馈:

import time
from tqdm import tqdm


def long_running_function(n, timeout=5):
    start_time = time.time()

    for _ in tqdm(list(range(n))):
        time.sleep(1)  # doing some expensive work...
        elapsed_time = time.time() - start_time
        if elapsed_time > timeout:
            raise TimeoutError("long_running_function took too long!")


long_running_function(100, timeout=10)
Run Code Online (Sandbox Code Playgroud)

如果运行此函数,该函数将在 10 秒后通过引发异常来停止自身执行。您可以在调用站点捕获此异常,并以您认为适当的任何方式对其进行响应。


如果你想变得聪明,你甚至可以将其分解在tqdm类似包装器中,如下所示:

def timed_loop(iterator, timeout):
    start_time = time.time()
    iterator = iter(iterator)

    while True:
        elapsed_time = time.time() - start_time
        if elapsed_time > timeout:
            raise TimeoutError("long_running_function took too long!")

        try:
            yield next(iterator)
        except StopIteration:
            pass


def long_running_function(n, timeout=5):
    for _ in timed_loop(tqdm(list(range(n))), timeout=timeout):
        time.sleep(0.1)


long_running_function(100, timeout=5)
Run Code Online (Sandbox Code Playgroud)

  • 这是错误的答案。@casper.dcl 作为作者/维护者给出了正确的答案 (2认同)