Python中的双进度条

问题描述 投票:17回答:3

有没有办法在Python中创建双进度条?我想在彼此内部运行两个循环。对于每个循环,我想要一个进度条。我的程序看起来像:

import time
for i1 in range(5):
    for i2 in range(300):
        # do something, e.g. sleep
        time.sleep(0.01)
        # update upper progress bar
    # update lower progress bar

中间某处的输出应该看起来像

50%|############################                                  |ETA: 0:00:02
80%|##################################################            |ETA: 0:00:04

已经存在的非常酷的progressbar模块似乎不支持这一点。

python progress-bar
3个回答
26
投票

使用nested progress bars feature of tqdm,一个极低开销,可定制的进度条库:

$ pip install -U tqdm

然后:

from tqdm import tqdm
import time
for i1 in tqdm(range(5)):
    for i2 in tqdm(range(300)):
        # do something, e.g. sleep
        time.sleep(0.01)

您也可以使用from tqdm import trange然后用tqdm(range(...))替换trange(...)。你也可以得到它working in a notebook


7
投票

它需要你移动光标位置。我写了一个hacky的事情来做它。

此脚本依赖于progressbar模块假定您处于一条新线以绘制进度条的事实。只需向上移动光标(使用“向上移动光标1行”的转义码),向下移动(仅使用换行符。我也可以使用转义码,但换行更容易,更快),可以保持多个进度酒吧。

import progressbar, time, sys

def up():
    # My terminal breaks if we don't flush after the escape-code
    sys.stdout.write('\x1b[1A')
    sys.stdout.flush()

def down():
    # I could use '\x1b[1B' here, but newline is faster and easier
    sys.stdout.write('\n')
    sys.stdout.flush()

# Total bar is at the bottom. Move down to draw it
down()
total = progressbar.ProgressBar(maxval=50)
total.start()

for i in range(1,51):
    # Move back up to prepare for sub-bar
    up()

    # I make a new sub-bar for every iteration, thinking it could be things
    # like "File progress", with total being total file progress.
    sub = progressbar.ProgressBar(maxval=50)
    sub.start()
    for y in range(51):
        sub.update(y)
        time.sleep(0.005)
    sub.finish()

    # Update total - The sub-bar printed a newline on finish, so we already
    # have focus on it
    total.update(i)
total.finish()

这当然有点hacky,但它完成了工作。我希望它有用。


0
投票

这可以通过atpbar轻松完成。

例如:

import time, random
from atpbar import atpbar

for i in atpbar(range(4), name='outer'):
    n = random.randint(1000, 10000)
    for j in atpbar(range(n), name='inner {}'.format(i)):
        time.sleep(0.0001)

上面的代码嵌套了for循环。外循环迭代四次。对于外循环的每次迭代,内循环迭代随机选择的次数。循环完成后,内循环的进度条向上移动。活动进度条保持在底部。进度条的快照可能看起来像

 100.00% :::::::::::::::::::::::::::::::::::::::: |     3287 /     3287 |:  inner 0
 100.00% :::::::::::::::::::::::::::::::::::::::: |     5850 /     5850 |:  inner 1
  50.00% ::::::::::::::::::::                     |        2 /        4 |:  outer  
  34.42% :::::::::::::                            |     1559 /     4529 |:  inner 2
© www.soinside.com 2019 - 2024. All rights reserved.