【问题标题】:tqdm: extract time passed + time remaining?tqdm:提取时间已过+剩余时间?
【发布时间】:2019-11-02 18:14:30
【问题描述】:

我一直在查看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]

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

【问题讨论】:

    标签: python printing progress-bar iterable tqdm


    【解决方案1】:

    你可以从format_dict和一些计算中得到elapsedremaining的时间。

    t = tqdm(total=100)
    ...
    elapsed = t.format_dict["elapsed"]
    rate = t.format_dict["rate"]
    remaining = (t.total - t.n) / rate if rate and t.total else 0  # Seconds*
    

    【讨论】:

      【解决方案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)
      

      如果您运行它,该函数将在 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)
      

      【讨论】:

      • 如果tqdm 目前没有办法允许这样做(这令人惊讶),这仍然是验证这一点的好答案。感谢您以允许时间检查的手动方式实现 tqdm 的所有代码,这是我自己没想到的。
      • 这是错误的答案。 @casper.dcl 作为作者/维护者给出了正确答案
      • 为什么一个明显错误的答案被接受,而正确和官方的答案却不被接受? OP 是否没有意识到可以更改接受的答案?无论哪种方式,这样做似乎都是公共利益
      【解决方案3】:

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

      from tqdm import tqdm
      
      with tqdm(total=100) as t:
          ...
          t.update()
          print(t.format_interval(t.format_dict['elapsed']))
      

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

      【讨论】:

      • tqdm format_dict 暴露了elapsed,请问有什么方法可以找回剩余的时间吗?
      猜你喜欢
      • 2022-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-02
      相关资源
      最近更新 更多