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

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

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

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


当前回答

下面是一个简短的解决方案,以编程方式构建加载条(您必须决定需要多长时间)。

import time

n = 33  # or however many loading slots you want to have
load = 0.01  # artificial loading time!
loading = '.' * n  # for strings, * is the repeat operator

for i in range(n+1):
    # this loop replaces each dot with a hash!
    print('\r%s Loading at %3d percent!' % (loading, i*100/n), end='')
    loading = loading[:i] + '#' + loading[i+1:]
    time.sleep(load)
    if i==n: print()

其他回答

这在Python3中非常简单:

   import time
   import math

    def show_progress_bar(bar_length, completed, total):
        bar_length_unit_value = (total / bar_length)
        completed_bar_part = math.ceil(completed / bar_length_unit_value)
        progress = "*" * completed_bar_part
        remaining = " " * (bar_length - completed_bar_part)
        percent_done = "%.2f" % ((completed / total) * 100)
        print(f'[{progress}{remaining}] {percent_done}%', end='\r')

    bar_length = 30
    total = 100
    for i in range(0, total + 1):
        show_progress_bar(bar_length, i, total)
        time.sleep(0.1)

    print('\n')

使用os_sys lib:

我在许多类型的条形图中使用它,例如:

from os_sys.progress import bar as Bar
bar = Bar('progresing: ', max=20)
for i in range(20):
    #do somthing
    bar.next()
bar.finish()

你的输出将是:

procesing:  |######                          | 2/10

请在os_sys的描述中阅读更多信息

已经有很多令人惊叹的答案,但我想分享我对进度条的解决方案。

from time import sleep

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

numbers = range(0, 1000)
numbersLen = len(numbers)
for i in numbers:
    sleep(0.01) # Do something usefull here
    progress_bar(i, numbersLen)

编辑:

如果你正在寻找一个条,调整它是基于终端的宽度和可能的消息在结束,然后这也是工作。请注意,如果终端太窄,消息将消失,因为如果它太宽,竖条将断开。

def progressBar(progress: float, total: float, message: str = ""):
    terminalWidth = get_terminal_size().columns
    width = int(terminalWidth / 4)
    percent = width * ((progress + 1) / total)
    bar = chr(9608) * int(percent) + "-" * (width - int(percent))
    if terminalWidth <= 40:
        message = ""
    else:
        message = message + (" " * (int(terminalWidth / 2) - len(message)))
    print(f"\r|{bar}| {(100/width)*percent:.2f}% " + message, end="\r")

使用进度库!

pip install progress

下面是我编写的一个自定义子类,用于将ETA/流逝时间格式化为更好读的格式:

import datetime
from progress.bar import IncrementalBar


class ProgressBar(IncrementalBar):
    '''
    My custom progress bar that:
       - Show %, count, elapsed, eta
       - Time is shown in H:M:S format
    '''

    message = 'Progress'
    suffix  = '%(percent).1f%% (%(index)d/%(max)d) -- %(elapsed_min)s (eta: %(eta_min)s)'

    def formatTime(self, seconds):
        return str(datetime.timedelta(seconds=seconds))

    @property
    def elapsed_min(self):
        return self.formatTime(self.elapsed)

    @property
    def eta_min(self):
        return self.formatTime(self.eta)

if __name__=='__main__':
    counter = 120
    bar     = ProgressBar('Processing', max=counter)

    for i in range(counter):
        bar.next()
        time.sleep(1)

    bar.finish()

iterrows的Progressbar。调整了@eusoubrasileiro代码,用于在循环遍历数据帧的行时显示进度。此外还显示百分比、ith/count、经过秒数、eps /sec、剩余秒数。允许指定第n个更新计数。

import time
import sys
def progressbar_iterrows(df, prefix="", size=60, file=sys.stdout, per=1000):
    count = len(df)
    t = 0
    def show(j,elapsed):
        avg = 0 if elapsed == 0 else j/elapsed
        remaining = 0 if avg == 0 else (count-j)/avg
        x = int(size*j/count)
        file.write("%s[%s%s] %i%% %i/%i elapsed:%i %i/sec remaining:%i\r" % (prefix, "#"*x, "."*(size-x), j/count, j, count, elapsed, avg, remaining))
        file.flush()
    file.write("Initializing ...\r")
    file.flush()
    for i, item in df.iterrows():
        yield i,item
        if t == 0:
            t = time.time()
        if i % per == 0:
            show(i,time.time()-t)
    file.write("\n")
    file.flush()

用法:

    for n,r in progressbar_iterrows(br_b_sections_df, "Processed: "):
        # do something

输出:

Processed: [........................] 0% 5000/28751240 elapsed:12 413/sec remaining:55054