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

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

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

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


当前回答

如果它是一个大循环,迭代次数固定,需要花费很多时间,你可以使用我做的这个函数。循环的每一次迭代都增加了进展。其中count是循环的当前迭代,total是循环的值,size(int)是你想要的条的大小,以10为增量,即(size 1 =10个字符,size 2 =20个字符)

import sys
def loadingBar(count,total,size):
    percent = float(count)/float(total)*100
    sys.stdout.write("\r" + str(int(count)).rjust(3,'0')+"/"+str(int(total)).rjust(3,'0') + ' [' + '='*int(percent/10)*size + ' '*(10-int(percent/10))*size + ']')

例子:

for i in range(0,100):
     loadingBar(i,100,2)
     #do some code 

输出:

i = 50
>> 050/100 [==========          ]

其他回答

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

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()

下面的代码是一个相当通用的解决方案,也有一个时间消耗和剩余时间估计。你可以使用任何可迭代对象。进度条的大小固定为25个字符,但可以使用完整、半块和四分之一块字符以1%的速度显示更新。输出如下所示:

 18% |████▌                    | \ [0:00:01, 0:00:06]

代码示例:

import sys, time
from numpy import linspace

def ProgressBar(iterObj):
  def SecToStr(sec):
    m, s = divmod(sec, 60)
    h, m = divmod(m, 60)
    return u'%d:%02d:%02d'%(h, m, s)
  L = len(iterObj)
  steps = {int(x):y for x,y in zip(linspace(0, L, min(100,L), endpoint=False),
                                   linspace(0, 100, min(100,L), endpoint=False))}
  qSteps = ['', u'\u258E', u'\u258C', u'\u258A'] # quarter and half block chars
  startT = time.time()
  timeStr = '   [0:00:00, -:--:--]'
  activity = [' -',' \\',' |',' /']
  for nn,item in enumerate(iterObj):
    if nn in steps:
      done = u'\u2588'*int(steps[nn]/4.0)+qSteps[int(steps[nn]%4)]
      todo = ' '*(25-len(done))
      barStr = u'%4d%% |%s%s|'%(steps[nn], done, todo)
    if nn>0:
      endT = time.time()
      timeStr = ' [%s, %s]'%(SecToStr(endT-startT),
                             SecToStr((endT-startT)*(L/float(nn)-1)))
    sys.stdout.write('\r'+barStr+activity[nn%4]+timeStr); sys.stdout.flush()
    yield item
  barStr = u'%4d%% |%s|'%(100, u'\u2588'*25)
  timeStr = '   [%s, 0:00:00]\n'%(SecToStr(time.time()-startT))
  sys.stdout.write('\r'+barStr+timeStr); sys.stdout.flush()

# Example
s = ''
for c in ProgressBar(list('Disassemble and reassemble this string')):
  time.sleep(0.2)
  s += c
print(s)

欢迎提出改进建议或其他意见。干杯!

使用动态进度,最酷的进度条!

要以一种有用的方式使用任何进度条框架,即获得完成百分比和预计到达时间(ETA),您需要能够告诉您的处理将有多少步骤。

然后,您只需插入一个yield来标记一个项目已被处理,然后就可以开始了!

def compute():
    for i in range(1000):
        ... # process items as usual.
        yield  # insert this :)

然后就像这样使用它:

from alive_progress import alive_bar

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

获得一个令人敬畏的和活着的进度条!

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

披露:我是alive-progress的作者,但它应该能很好地解决你的问题!阅读https://github.com/rsalmei/alive-progress上的文档了解更多信息。现在它也在木星笔记本!以下是它能做的更多例子:

使用tqdm (conda install tqdm或pip 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。笔记本电脑工作在两个终端和笔记本电脑。

tqdm。Contrib包含一些辅助函数,用于执行枚举、映射和压缩等操作。在tqdm.contrib.concurrent中有并发映射。

你甚至可以使用tqdm.contrib.telegram或tqdm.contrib.discord从jupyter笔记本断开连接后将进度发送到你的手机。

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