Python进度条

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python进度条相关的知识,希望对你有一定的参考价值。

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

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

请注意,我需要实时,所以我无法弄清楚该怎么做。我需要一个thread吗?我不知道。

现在我正在执行函数时不打印任何内容,但是进度条会很好。此外,我更感兴趣的是从代码的角度来看如何做到这一点。

答案

有特定的库(like this one here)但也许非常简单的事情会做:

import time
import sys

toolbar_width = 40

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

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

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

注意:progressbar2progressbar的一个分支,多年来一直没有维护。

另一答案

你可以使用tqdm

from tqdm import tqdm

with tqdm(total=100, desc="Adding Users", bar_format="{l_bar}{bar} [ time left: {remaining} ]") as pbar:
    for i in range(100):
        time.sleep(3)
        pbar.update(1)

在此示例中,进度条运行了5分钟,显示如下:

Adding Users:   3%|█████▊                                     [ time left: 04:51 ]                                                                                                        

您可以根据需要进行更改和自定义。

另一答案

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

import sys
def loadingBar(count,total,size):
    percent = float(count)/float(total)*100
    sys.stdout.write("
" + 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 [==========          ]
另一答案

使用此库:fishGitHub)。

用法:

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

玩得开心!

另一答案

在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='
')

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

    print('
')
另一答案

我喜欢这个page

从简单示例开始,然后转到多线程版本。开箱即用。不需要第三方包裹。

代码看起来像这样:

import time
import sys

def do_task():
    time.sleep(1)

def example_1(n):
    for i in range(n):
        do_task()
        print '.',
        sys.stdout.flush()
    print ' Done!'

print 'Starting ',
example_1(10)

或者这里是使用线程的示例,以便在程序运行时运行旋转加载栏:

import sys
import time
import threading

class progress_bar_loading(threading.Thread):

    def run(self):
            global stop
            global kill
            print 'Loading....  ',
            sys.stdout.flush()
            i = 0
            while stop != True:
                    if (i%4) == 0: 
                        sys.stdout.write('/')
                    elif (i%4) == 1: 
                        sys.stdout.write('-')
                    elif (i%4) == 2: 
                        sys.stdout.write('\')
                    elif (i%4) == 3: 
                        sys.stdout.write('|')

                    sys.stdout.flush()
                    time.sleep(0.2)
                    i+=1

            if kill == True: 
                print ' ABORT!',
            else: 
                print ' done!',


kill = False      
stop = False
p = progress_bar_loading()
p.start()

try:
    #anything you want to run. 
    time.sleep(1)
    stop = True
except KeyboardInterrupt or EOFError:
         kill = True
         stop = True
另一答案

下面的代码是一个非常通用的解决方案,还有一个时间和剩余时间估计。你可以使用任何iterable。进度条的固定大小为25个字符,但它可以使用完整,半个和四分之一块字符以1%的步长显示更新。输出如下所示:

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

代码示例:

import sys, time
from numpy import linspace

def ProgressBar(iterObj, refreshTime=10):
  #refreshTime=10: refresh the time estimate at least every 10 sec.
  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(np.linspace(0,L,  min(100,L),endpoint=False), 
                                     np.linspace(0,100,min(100,L),endpoint=False))}
  qSteps  = ['', u'u258E',u'u258C',u'u258A'] # quarter and half block chars
  startT  = endT = time.time()
  timeStr = ' [0:00:00, -:--:--]'
  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('
'+barStr+timeStr); sys.stdout.flush()
    elif time.time()-endT > refreshTime:
      endT    = time.time()
      timeStr = ' [%s, %s]'%(SecToStr(endT-startT), SecToStr((endT-startT)*(L/float(nn)-1)))
      sys.stdout.write('
'+barStr+timeStr); sys.stdout.flush()
    yield item
  barStr  = u'%4d%% |%s|'%(100, u'u2588'*25)
  timeStr = ' [%s, 0:00:00]
'%(SecToStr(time.time()-startT))
  sys.stdout.write('
'+barStr+timeStr); sys.stdout.flush()

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

欢迎提出改进建议或其他意见。玩得开心。

另一答案

在jupyter笔记本中运行时,使用普通tqdm不起作用,因为它在多行上写入输出。请改用:

import time
from tqdm import tqdm_notebook as tqdm

for i in tqdm(range(100))
    time.sleep(0.5)
另一答案

如果您的工作无法分解为可测量的块,您可以在新线程中调用函数并计算所需的时间:

import thread
import time
import sys

def work():
    time.sleep( 5 )

def locked_call( func, lock ):
    lock.acquire()
    func()
    lock.release()

lock = thread.allocate_lock()
thread.start_new_thread( locked_call, ( work, lock, ) )

# This part is icky...
while( not lock.locked() ):
    time.sleep( 0.1 )

while( lock.locked() ):
    sys.stdout.write( "*" )
    sys.stdout.flush()
    time.sleep( 1 )
print "
Work Done"

显然,您可以根据需要提高定时精度。

另一答案

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

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('
%s Loading at %3d percent!' % (loading, i*100/n), end='')
    loading = loading[:i] + '#' + loading[i+1:]
    time.sleep(load)