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

例如,一个函数需要一段时间才能完成,完成后返回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 [==========          ]

其他回答

试试https://pypi.python.org/pypi/progress上的progress。

from progress.bar import Bar

bar = Bar('Processing', max=20)
for i in range(20):
    # Do some work
    bar.next()
bar.finish()

结果将是如下所示的条:

Processing |#############                   | 42/100

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

没有外部包。一段现成的代码。

您可以自定义进度条符号“#”,进度条大小,文本前缀等。

Python 3.3 +

import sys
def progressbar(it, prefix="", size=60, out=sys.stdout): # Python3.3+
    count = len(it)
    def show(j):
        x = int(size*j/count)
        print("{}[{}{}] {}/{}".format(prefix, "#"*x, "."*(size-x), j, count), 
                end='\r', file=out, flush=True)
    show(0)
    for i, item in enumerate(it):
        yield item
        show(i+1)
    print("\n", flush=True, file=out)

用法:

import time    
for i in progressbar(range(15), "Computing: ", 40):
    time.sleep(0.1) # any code you need

要填满整个字符空间,请使用unicode u"█"字符替换"#"。使用for i in progressbar(range(100)):…你会得到:

不需要第二个线程。上面的一些解决方案/包需要。 适用于任何可迭代对象,它指的是任何可以使用len()的对象。一个列表,一个字典,比如[' A ', 'b', 'c'…' g '] 使用生成器的工作只需要用list()来包装它。例如,对于i in progressbar(list(your_generator), "Computing: ", 40):除非工作在生成器中完成。在这种情况下,您需要另一种解决方案(如tqdm)。

您还可以通过将out更改为sys来更改输出。例如Stderr。


Python 3.6+ (f-string)

def progressbar(it, prefix="", size=60, out=sys.stdout): # Python3.6+
    count = len(it)
    def show(j):
        x = int(size*j/count)
        print(f"{prefix}[{u'█'*x}{('.'*(size-x))}] {j}/{count}", end='\r', file=out, flush=True)
    show(0)
    for i, item in enumerate(it):
        yield item
        show(i+1)
    print("\n", flush=True, file=out)

Python 2 (old-code)

import sys
def progressbar(it, prefix="", size=60, out=sys.stdout):
    count = len(it)
    def show(j):
        x = int(size*j/count)
        out.write("%s[%s%s] %i/%i\r" % (prefix, u"#"*x, "."*(size-x), j, count))
        out.flush()        
    show(0)
    for i, item in enumerate(it):
        yield item
        show(i+1)
    out.write("\n")
    out.flush()

这里有一个非常简单的版本,如果你有一个循环,只是想了解迭代的进展,比如每一个点,比如说,5000次迭代。

my_list = range(0,100000)

counter = 0
for x in my_list:
    #your code here

    counter = counter + 1
    if counter % 5000 == 0:
        print(".", end="") # end="" avoids a newline, keeps dots together

print() #this makes sure whatever you print next is in a new line

My_list不是方案的一部分。使用你自己的迭代对象,不管你在循环什么。 这个版本没有提前告诉您总共有多少次迭代。

您应该将进度条链接到手头的任务(以便它度量进度:D)。例如,如果您正在对一个文件进行ftp传输,您可以告诉ftplib获取一个特定大小的缓冲区,比如128K,然后您将128K所代表的文件大小的百分比添加到进度条中。如果您正在使用CLI,并且进度表有20个字符长,那么当文件传输了1/20时,您将添加一个字符。