Python 进度条

562 投票
49 回答
1030443 浏览
提问于 2025-04-16 00:41

我该如何在脚本执行一些可能需要时间的任务时使用进度条呢?

比如说,有一个函数需要一些时间才能完成,完成后返回True。我该如何在这个函数执行的过程中显示一个进度条呢?

需要注意的是,我希望这个进度条是实时更新的,所以我不知道该怎么做。是不是需要用到线程呢?我完全没有头绪。

现在在函数执行的时候我什么都没有打印,但有一个进度条会很好。另外,我更想知道从代码的角度来看,这该怎么实现。

49 个回答

271

使用alive-progress,这是最酷的进度条!只需运行pip install alive-progress,就可以开始使用了!

展示alive-progress示例的GIF

要有效使用任何进度条,比如获取完成的百分比和预计完成时间,你需要告诉它总共有多少项。这样alive-progress就能跟踪你当前的处理进度,以及还需要多长时间!
如果你无法估算总数也没关系,alive-progress仍然可以正常工作。

使用它时,你可以直接控制alive-progress的进度条:

def compute():
    with alive_bar(1000) as bar:  # your expected total
        for item in items:        # the original loop
            print(item)           # your actual processing here
            bar()                 # call `bar()` at the end


compute()

或者,如果你想把代码分开处理,只需在你的处理代码中插入一个yield(用来标记某项已处理),然后像这样控制alive-progress的进度条:

def compute():
    for item in items:
        print(item)
        yield                  # simply insert this :)


with alive_bar(1000) as bar:
    for i in compute():
        bar()

无论哪种方式,你都会得到一个很棒的动态进度条!

|█████████████▎                      | ▅▃▁ 321/1000 [32%] in 8s (40.1/s, eta: 16s)

而且它开箱即用就支持很多高级选项!! 一些高级选项

声明:我是alive-progress的骄傲作者,它在GitHub上有超过5000个⭐️!
查看文档了解所有高级功能,地址是https://github.com/rsalmei/alive-progress

看看它在旋转和条形小部件中可以做的更多动画: 展示各种alive-progress样式的GIF

它也可以在Jupyter Notebook上使用! 展示alive-progress在Jupyter Notebook上的GIF

你甚至可以设计自己的动画!! 展示动画设计器的GIF

758

使用 tqdm (可以通过 conda install tqdmpip install tqdm 安装),你可以在循环中轻松添加一个进度条,几乎只需一秒钟:

from time import sleep
from tqdm import tqdm
for i in tqdm(range(10)):
    sleep(3)

 60%|██████    | 6/10 [00:18<00:12,  0.33 it/s]

另外,还有一个 笔记本版本

from tqdm.notebook import tqdm
for i in tqdm(range(100)):
    sleep(3)

你可以使用 tqdm.auto 来代替 tqdm.notebook,这样在终端和笔记本中都能使用。

tqdm.contrib 包含了一些辅助函数,可以用来处理像 enumeratemapzip 这样的操作。在 tqdm.contrib.concurrent 中还有并发处理的功能。

你甚至可以在断开与 Jupyter 笔记本的连接后,通过 tqdm.contrib.telegramtqdm.contrib.discord 将进度发送到你的手机上。

GIF展示了使用 tqdm.contrib.telegram 在 Telegram 移动应用中显示进度条的示例

231

有一些特定的库(比如这个),但也许简单一点的方式就可以了:

import time
import sys

toolbar_width = 40

# setup toolbar
sys.stdout.write("[%s]" % (" " * toolbar_width))
sys.stdout.flush()
sys.stdout.write("\b" * (toolbar_width+1)) # return to start of line, after '['

for i in range(toolbar_width):
    time.sleep(0.1) # do real work here
    # update the bar
    sys.stdout.write("-")
    sys.stdout.flush()

sys.stdout.write("]\n") # this ends the progress bar

注意:progressbar2progressbar 的一个分支,而后者已经很多年没有维护了。

撰写回答