实现如下所示的状态栏:

[==========                ]  45%
[================          ]  60%
[==========================] 100%

我想把这个打印到标准输出,并保持刷新,而不是打印到另一行。如何做到这一点?


当前回答

只使用内置的sys:

import sys

def print_progress_bar(index, total, label):
    n_bar = 50  # Progress bar width
    progress = index / total
    sys.stdout.write('\r')
    sys.stdout.write(f"[{'=' * int(n_bar * progress):{n_bar}s}] {int(100 * progress)}%  {label}")
    sys.stdout.flush()

用法:

foo_list = ["a", "b", "c", "d"]
total = len(foo_list)

for index, item in enumerate(foo_list):
    print_progress_bar(index, total, "foo bar")
    sleep(0.5)

Enumerate (foo_list)使您可以在循环期间访问索引值。

输出:

[================================================  ] 96%  foo bar  

其他回答

在这里和其他地方的一些答案的基础上,我编写了这个简单的函数,它显示一个进度条和经过/估计的剩余时间。应该在大多数基于unix的机器上运行。

import time
import sys

percent = 50.0
start = time.time()
draw_progress_bar(percent, start)


def draw_progress_bar(percent, start, barLen=20):
sys.stdout.write("\r")
progress = ""
for i in range(barLen):
    if i < int(barLen * percent):
        progress += "="
    else:
        progress += " "

elapsedTime = time.time() - start;
estimatedRemaining = int(elapsedTime * (1.0/percent) - elapsedTime)

if (percent == 1.0):
    sys.stdout.write("[ %s ] %.1f%% Elapsed: %im %02is ETA: Done!\n" % 
        (progress, percent * 100, int(elapsedTime)/60, int(elapsedTime)%60))
    sys.stdout.flush()
    return
else:
    sys.stdout.write("[ %s ] %.1f%% Elapsed: %im %02is ETA: %im%02is " % 
        (progress, percent * 100, int(elapsedTime)/60, int(elapsedTime)%60,
         estimatedRemaining/60, estimatedRemaining%60))
    sys.stdout.flush()
    return

如果你正在开发一个命令行界面,我建议你看看click,它非常好:

import click
import time

for filename in range(3):
    with click.progressbar(range(100), fill_char='=', empty_char=' ') as bar:
        for user in bar:
            time.sleep(0.01)

下面是你得到的输出:

$ python test.py
  [====================================]  100%
  [====================================]  100%
  [=========                           ]   27%

对于Python 3.6,以下工作为我更新输出内联:

for current_epoch in range(10):
    for current_step) in range(100):
        print("Train epoch %s: Step %s" % (current_epoch, current_step), end="\r")
print()

我发现有用的库tqdm (https://github.com/tqdm/tqdm/,以前是:https://github.com/noamraph/tqdm)。它可以自动估计完成时间,也可以用作迭代器。

用法:

import tqdm
import time

for i in tqdm.tqdm(range(1000)):
    time.sleep(0.01)
    # or other long operations

结果:

|####------| 450/1000  45% [elapsed: 00:04 left: 00:05, 99.15 iters/sec]

TQDM可以包装任何可迭代对象。

要成为纯python并且不进行系统调用:

from time import sleep

for i in range(21):
    spaces = " " * (20 - i)
    percentage = 5*i
    print(f"\r[{'='*i}{spaces}]{percentage}%", flush=True, end="")
    sleep(0.25)