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

例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?

请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。

现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。


当前回答

我真的很喜欢python-progressbar,因为它使用起来非常简单。

对于最简单的情况,它是:

import progressbar
import time

progress = progressbar.ProgressBar()
for i in progress(range(80)):
    time.sleep(0.01)

外观可以自定义,它可以显示估计的剩余时间。举个例子,使用与上面相同的代码,但是包含:

progress = progressbar.ProgressBar(widgets=[progressbar.Bar('=', '[', ']'), ' ',
                                            progressbar.Percentage(), ' ',
                                            progressbar.ETA()])

其他回答

这个进度条显示了每完成2%的点和每完成10%的数字。

import sys

def ProgressBar (num, total, nextPercent, nextPoint):
    num = float (num)
    total = float (total) - 1
    if not nextPoint:
        nextPoint = 0.0
    if not nextPercent:
        nextPoint += 2.0
        sys.stdout.write ("[0%")
        nextPercent = 10
    elif num == total:
        sys.stdout.write ("100%]\n")
        nextPercent += 10
    elif not nextPoint:
        nextPoint = 0.0
    elif num / total * 100 >= nextPercent:
        sys.stdout.write (str(int (nextPercent)) + "%")
        nextPercent += 10
    elif num / total * 100 >= nextPoint:
        sys.stdout.write (":")
        nextPoint += 2
    return (nextPercent, nextPoint)

nextPercent, nextPoint = 0, 0
total = 1000

for num in range (total):
    nextPercent, nextPoint = ProgressBar (num, total, nextPercent, nextPoint)

结果:

>>> 
[0%::::10%:::::20%:::::30%:::::40%:::::50%:::::60%:::::70%:::::80%:::::90%:::::100%]
>>> 

使用这个库:fish (GitHub)。

用法:

>>> import fish
>>> while churning:
...     churn_churn()
...     fish.animate()

玩得开心!

一个简单的联机程序:

K = 628318
for k in range(K):
    # your stuff
    print(end="\r|%-80s|" % ("="*int(80*k/(K-1))))
|=====================================================================       |

80是棒子的长度。最终,您需要一个最终的print()。

不要忘了数字进步指示器:

K = 628318
for k in range(K):
    # your stuff
    print(end="\r%6.2f %%" % (k/(K-1)*100))
 94.53 %

如果需要,将两者结合起来并不难。

键是“回车”\r和打印中默认end=“\n”的抑制键。

在这里寻找等效的解决方案后,我只是为我的需求做了一个简单的进度类。我想我应该把它贴出来。

from __future__ import print_function
import sys
import re


class ProgressBar(object):
    DEFAULT = 'Progress: %(bar)s %(percent)3d%%'
    FULL = '%(bar)s %(current)d/%(total)d (%(percent)3d%%) %(remaining)d to go'

    def __init__(self, total, width=40, fmt=DEFAULT, symbol='=',
                 output=sys.stderr):
        assert len(symbol) == 1

        self.total = total
        self.width = width
        self.symbol = symbol
        self.output = output
        self.fmt = re.sub(r'(?P<name>%\(.+?\))d',
            r'\g<name>%dd' % len(str(total)), fmt)

        self.current = 0

    def __call__(self):
        percent = self.current / float(self.total)
        size = int(self.width * percent)
        remaining = self.total - self.current
        bar = '[' + self.symbol * size + ' ' * (self.width - size) + ']'

        args = {
            'total': self.total,
            'bar': bar,
            'current': self.current,
            'percent': percent * 100,
            'remaining': remaining
        }
        print('\r' + self.fmt % args, file=self.output, end='')

    def done(self):
        self.current = self.total
        self()
        print('', file=self.output)

例子:

from time import sleep

progress = ProgressBar(80, fmt=ProgressBar.FULL)

for x in xrange(progress.total):
    progress.current += 1
    progress()
    sleep(0.1)
progress.done()

将打印以下内容:

[========] 17/80 (21%) 63

已经有很多好的答案,但添加这个特定的基于@HandyGold75的答案,我希望它在特定的上下文中是callabe,有一个初始的msg,加上在结束时的几秒钟的时间反馈。

from time import sleep, time


class ProgressBar:
    def __init__(self, total: float, width: int = 50, msg: str = ""):
    self.total = total
    self.width = width
    self.start: float = time()
    if msg:
        print(f"{msg}")

    def progress(self, progress: float):
        percent = self.width * ((progress) / self.total)
        bar = chr(9608) * int(percent) + "-" * (self.width - int(percent))
        print(
            f"\r|{bar}| {(100/self.width)*percent:.2f}% "
            f"[{progress} of {self.total}]",
            end="\r",
        )

    def __enter__(self):
        return self.progress

    def __exit__(self, type, value, traceback):
        end: float = time()
        print(f"\nFinished after {end - self.start: .3f} seconds.")


# USAGE
total_loops = 150
with ProgressBar(total=total_loops) as progress:
    for i in range(total_loops):
        sleep(0.01)  # Do something usefull here
        progress(i + 1)