Python进度条

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

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

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

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

837842 次浏览

有一些特定的库(比如这个),但也许一些非常简单的库就可以做到:

import time
import sys


toolbar_width = 40


# setup toolbar
sys.stdout.write("[%s]" % (" " * toolbar_width))
sys.stdout.flush()
sys.stdout.write("\b" * (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("]\n") # this ends the progress bar

注意:progressbar2progressbar的一个分支,已经很多年没有维护了。

如果你的工作不能被分解成可测量的块,你可以在一个新的线程中调用你的函数,并记录它所花费的时间:

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 "\nWork Done"

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

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

使用这个库:fish (GitHub)。

用法:

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

玩得开心!

对于类似的应用程序(在循环中跟踪进度),我简单地使用python-progressbar:

他们的例子是这样的,

from progressbar import *               # just a simple progress bar




widgets = ['Test: ', Percentage(), ' ', Bar(marker='0',left='[',right=']'),
' ', ETA(), ' ', FileTransferSpeed()] #see docs for other options


pbar = ProgressBar(widgets=widgets, maxval=500)
pbar.start()


for i in range(100,500+1,50):
# here do something long at each iteration
pbar.update(i) #this adds a little symbol at each iteration
pbar.finish()
print

上面的建议非常好,但我认为大多数人只是想要一个现成的解决方案,不依赖于外部包,但也是可重用的。

我得到了上面所有的优点,并把它做成了一个函数,以及一个测试用例。

要使用它,只需复制“def update_progress(progress)”下面的行,而不是测试脚本。不要忘记导入sys。在需要显示或更新进度条时调用此函数。

这是通过直接向控制台发送“\r”符号来将光标移回起始位置。python中的"print"不能识别上述符号,因此我们需要'sys'

import time, sys


# update_progress() : Displays or updates a console progress bar
## Accepts a float between 0 and 1. Any int will be converted to a float.
## A value under 0 represents a 'halt'.
## A value at 1 or bigger represents 100%
def update_progress(progress):
barLength = 10 # Modify this to change the length of the progress bar
status = ""
if isinstance(progress, int):
progress = float(progress)
if not isinstance(progress, float):
progress = 0
status = "error: progress var must be float\r\n"
if progress < 0:
progress = 0
status = "Halt...\r\n"
if progress >= 1:
progress = 1
status = "Done...\r\n"
block = int(round(barLength*progress))
text = "\rPercent: [{0}] {1}% {2}".format( "#"*block + "-"*(barLength-block), progress*100, status)
sys.stdout.write(text)
sys.stdout.flush()




# update_progress test script
print "progress : 'hello'"
update_progress("hello")
time.sleep(1)


print "progress : 3"
update_progress(3)
time.sleep(1)


print "progress : [23]"
update_progress([23])
time.sleep(1)


print ""
print "progress : -10"
update_progress(-10)
time.sleep(2)


print ""
print "progress : 10"
update_progress(10)
time.sleep(2)


print ""
print "progress : 0->1"
for i in range(101):
time.sleep(0.1)
update_progress(i/100.0)


print ""
print "Test completed"
time.sleep(10)

这是测试脚本显示的结果(最后一个进度条是动画):

progress : 'hello'
Percent: [----------] 0% error: progress var must be float
progress : 3
Percent: [##########] 100% Done...
progress : [23]
Percent: [----------] 0% error: progress var must be float


progress : -10
Percent: [----------] 0% Halt...


progress : 10
Percent: [##########] 100% Done...


progress : 0->1
Percent: [##########] 100% Done...
Test completed

@Massagran:它在我的程序中工作得很好。此外,我们需要添加一个计数器来指示循环时间。该计数器作为方法update的参数。 例如:读取测试文件的所有行,并对它们进行处理。假设函数dosth()与变量i.

无关
lines = open(sys.argv[1]).readlines()
i = 0
widgets=[Percentage(), Bar()]
pbar = ProgressBar(widgets=widgets,maxval=len(lines)).start()
pbar.start()
for line in lines:<pre>
dosth();
i += 1
pbar.update(i)</pre>
pbar.finish()

变量i通过方法update控制pbar的状态

尝试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

使用tqdm (conda install tqdmpip 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.notebook在终端和笔记本上工作。

tqdm.contrib包含一些帮助函数来做一些事情,比如enumeratemapzip。在tqdm.contrib.concurrent中有并发映射。

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

GIF显示使用tqdm.contrib.telegram在Telegram移动应用程序中显示进度条的输出示例

我喜欢这个页面

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

代码看起来像这样:

import time
import sys


def do_task():
time.sleep(1)


def example_1(n):
for i in range(n):
do_task()
print '\b.',
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('\b/')
elif (i%4) == 1:
sys.stdout.write('\b-')
elif (i%4) == 2:
sys.stdout.write('\b\\')
elif (i%4) == 3:
sys.stdout.write('\b|')


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


if kill == True:
print '\b\b\b\b ABORT!',
else:
print '\b\b 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

我真的很喜欢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()])

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

你可以定制进度条符号"#",进度条size,文本prefix等。

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)): ...可以得到:

enter image description here

  • < p > 不需要第二个线程。上面的一些解决方案/包需要。

  • 适用于任何可迭代对象它表示任何len()可以用于的对象。list,任何东西的dict,例如['a', 'b', 'c' ... 'g']

  • 使用发电机只需要用一个list()来包装它。例如for 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()

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

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

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

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 to go

我喜欢Brian Khuu的回答是,因为它简单,不需要外部包。我做了一点改动,所以我在这里添加了我的版本:

import sys
import time




def updt(total, progress):
"""
Displays or updates a console progress bar.


Original source: https://stackoverflow.com/a/15860757/1391441
"""
barLength, status = 20, ""
progress = float(progress) / float(total)
if progress >= 1.:
progress, status = 1, "\r\n"
block = int(round(barLength * progress))
text = "\r[{}] {:.0f}% {}".format(
"#" * block + "-" * (barLength - block), round(progress * 100, 0),
status)
sys.stdout.write(text)
sys.stdout.flush()




runs = 300
for run_num in range(runs):
time.sleep(.1)
updt(runs, run_num + 1)

它取运行总数(total)和目前处理的运行数(progress),假设total >= progress。结果如下所示:

[#####---------------] 27%

我喜欢盖伯瑞尔的答案,但我改变了它的灵活性。您可以将bar-length发送到函数,并获得您想要的任何长度的进度条。进度条的长度不能为零或负。同样,你也可以像盖伯瑞尔 answer一样使用这个函数(请看例子#2)。

import sys
import time


def ProgressBar(Total, Progress, BarLength=20, ProgressIcon="#", BarIcon="-"):
try:
# You can't have a progress bar with zero or negative length.
if BarLength <1:
BarLength = 20
# Use status variable for going to the next line after progress completion.
Status = ""
# Calcuting progress between 0 and 1 for percentage.
Progress = float(Progress) / float(Total)
# Doing this conditions at final progressing.
if Progress >= 1.:
Progress = 1
Status = "\r\n"    # Going to the next line
# Calculating how many places should be filled
Block = int(round(BarLength * Progress))
# Show this
Bar = "[{}] {:.0f}% {}".format(ProgressIcon * Block + BarIcon * (BarLength - Block), round(Progress * 100, 0), Status)
return Bar
except:
return "ERROR"


def ShowBar(Bar):
sys.stdout.write(Bar)
sys.stdout.flush()


if __name__ == '__main__':
print("This is a simple progress bar.\n")


# Example #1:
print('Example #1')
Runs = 10
for i in range(Runs + 1):
progressBar = "\rProgress: " + ProgressBar(10, i, Runs)
ShowBar(progressBar)
time.sleep(1)


# Example #2:
print('\nExample #2')
Runs = 10
for i in range(Runs + 1):
progressBar = "\rProgress: " + ProgressBar(10, i, 20, '|', '.')
ShowBar(progressBar)
time.sleep(1)


print('\nDone.')


# Example #2:
Runs = 10
for i in range(Runs + 1):
ProgressBar(10, i)
time.sleep(1)

结果:

这是一个简单的进度条。

示例# 1

进度:[###-------]30%

例# 2

进步 : [||||||||||||........) 60%

完成了。

如果它是一个大循环,迭代次数固定,需要花费很多时间,你可以使用我做的这个函数。循环的每一次迭代都增加了进展。其中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 [==========          ]

PyProg试试。PyProg是Python的一个开源库,用于创建超级可定制的进度指示器。酒吧。

它目前的版本是1.0.2;它托管在Github上,在PyPI上可用(链接如下)。它与Python 3 &2,它也可以与Qt控制台使用。

它真的很容易使用。以下代码:

import pyprog
from time import sleep


# Create Object
prog = pyprog.ProgressBar(" ", "", 34)
# Update Progress Bar
prog.update()


for i in range(34):
# Do something
sleep(0.1)
# Set current status
prog.set_stat(i + 1)
# Update Progress Bar again
prog.update()


# Make the Progress Bar final
prog.end()

会产生:

Initial State:
Progress: 0% --------------------------------------------------


When half done:
Progress: 50% #########################-------------------------


Final State:
Progress: 100% ##################################################

我实际上做了PyProg,因为我需要一个简单但超级可定制的进度条库。你可以很容易地使用:pip install pyprog安装它。

PyProg Github: https://github.com/Bill13579/pyprog
PyPI: https://pypi.python.org/pypi/pyprog/ < / p >

下面的代码是一个相当通用的解决方案,也有一个时间消耗和剩余时间估计。你可以使用任何可迭代对象。进度条的大小固定为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)

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

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

你也可以使用启发。主要的优点是你可以在不覆盖进度条的同时记录日志。

import time
import enlighten


manager = enlighten.Manager()
pbar = manager.counter(total=100)


for num in range(1, 101):
time.sleep(0.05)
print('Step %d complete' % num)
pbar.update()

它还可以处理多个进度条。

import time
import enlighten


manager = enlighten.Manager()
odds = manager.counter(total=50)
evens = manager.counter(total=50)


for num in range(1, 101):
time.sleep(0.05)
if num % 2:
odds.update()
else:
evens.update()

当在jupyter笔记本上运行时,使用普通的tqdm无法工作,因为它将输出写在多行上。用这个代替:

import time
from tqdm import tqdm_notebook as tqdm


for i in tqdm(range(100))
time.sleep(0.5)

一个更通用的jelde015的答案(当然是他的功劳)

用于更新加载条手动将是:

import sys
from math import *




def loadingBar(i, N, size):
percent = float(i) / float(N)
sys.stdout.write("\r"
+ str(int(i)).rjust(3, '0')
+"/"
+str(int(N)).rjust(3, '0')
+ ' ['
+ '='*ceil(percent*size)
+ ' '*floor((1-percent)*size)
+ ']')

称之为:

loadingBar(7, 220, 40)

将结果:

007/220 [=                                       ]

只要你想在任何时候用当前的i值调用它。

size设置为该栏应有的字符数

使用os_sys库:

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

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的描述中阅读更多信息

我想我有点晚了,但这应该适用于使用python 3的当前版本的人,因为这使用了“f-strings”,正如Python 3.6 PEP 498中介绍的那样:

代码

from numpy import interp


class Progress:
def __init__(self, value, end, title='Downloading',buffer=20):
self.title = title
#when calling in a for loop it doesn't include the last number
self.end = end -1
self.buffer = buffer
self.value = value
self.progress()


def progress(self):
maped = int(interp(self.value, [0, self.end], [0, self.buffer]))
print(f'{self.title}: [{"#"*maped}{"-"*(self.buffer - maped)}]{self.value}/{self.end} {((self.value/self.end)*100):.2f}%', end='\r')

例子

#some loop that does perfroms a task
for x in range(21)  #set to 21 to include until 20
Progress(x, 21)

输出

Downloading: [########------------] 8/20 40.00%

这是创建进度条的简单方法

import time,sys
toolbar_width = 50
# setting up toolbar [-------------------------------------]
sys.stdout.write("[%s]"%(("-")*toolbar_width))
sys.stdout.flush()
# each hash represents 2 % of the progress
for i in range(toolbar_width):
sys.stdout.write("\r") # return to start of line
sys.stdout.flush()
sys.stdout.write("[")#Overwrite over the existing text from the start
sys.stdout.write("#"*(i+1))# number of # denotes the progress completed
sys.stdout.flush()
time.sleep(0.1)

你可以使用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 ]

您可以随心所欲地更改它和自定义它。

使用alive-progress,最酷的进度条!

GIF显示一个活生生的进程的例子

要以一种有用的方式使用任何进度条框架,即获得完成百分比和预计到达时间(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文档了解更多信息。现在它也在木星笔记本!以下是它能做的更多例子:

GIF显示各种风格的live-progress

GIF显示Jupyter笔记本的活动进度

这个进度条显示了每完成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%]
>>>

我使用format()方法创建了一个加载条。以下是我的解决方案:

import time


loadbarwidth = 23


for i in range(1, loadbarwidth + 1):
time.sleep(0.1)


strbarwidth = '[{}{}] - {}\r'.format(
(i * '#'),
((loadbarwidth - i) * '-'),
(('{:0.2f}'.format(((i) * (100/loadbarwidth))) + '%'))
)


print(strbarwidth ,end = '')


print()

输出:

[#######################] - 100.00%

使用进步的图书馆!

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

这是我的简单解决方案:

import time


def progress(_cur, _max):
p = round(100*_cur/_max)
b = f"Progress: {p}% - ["+"."*int(p/5)+" "*(20-int(p/5))+"]"
print(b, end="\r")


# USAGE:
for i in range(0,101):
time.sleep(0.1)
progress(i,100)


print("..."*5, end="\r")
print("Done")

这里有一个简单的解决方案!

void = '-'
fill = '#'
count = 100/length
increaseCount = 0
for i in range(length):
print('['+(fill*i)+(void*(length-i))+'] '+str(int(increaseCount))+'%',end='\r')
increaseCount += count
time.sleep(0.1)
print('['+(fill*(i+1))+(void*(length-(i+1)))+'] '+str(int(increaseCount))+'%',end='\n')

注意:您可以修改填充和“;空白”;如果你愿意,你可以有个性。

加载条(图片)

一个非常简单的方法:

def progbar(count: int) -> None:
for i in range(count):
print(f"[{i*'#'}{(count-1-i)*' '}] - {i+1}/{count}", end="\r")
yield i
print('\n')

以及用法:

from time import sleep


for i in progbar(10):
sleep(0.2) #whatever task you need to do

这里有一个非常简单的版本,如果你有一个循环,只是想了解迭代的进展,比如每一个点,比如说,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不是方案的一部分。使用你自己的迭代对象,不管你在循环什么。 这个版本不会提前告诉你总共有多少次迭代

我使用wget,如果在mac或linux上,你必须在windows或终端中的cmd提示符中安装模块

pip install wget

这非常简单,只需使用download()函数即可

import wget
url = input("Enter Url to download: ")
wget.download(url)

TQDM也是一个选择,你也必须下载这个模块。

pip install tqdm

现在确保导入模块,设置范围和pass

from tqdm import tqdm
for i in tqdm(range(int(9e7))):
pass

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
from IPython.display import clear_output
progress_bar=u"\u001b[7m Loading: "
for i in range(100):
clear_output(wait=True)
progress_bar+=u"\u001b[7m "
print(progress_bar+str(i+1)+"%")
time.sleep(0.03) #you can change the speed

output

一个简单的联机程序:

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和在print中抑制默认end="\n"

回答没有外部库的简单进度条

import time, sys


def progress(size):
for item in range(size):
if(item==0):
print("[",end="")


elif(item==size-1):
print("]",end="\n")


else:
#main work goes here
time.sleep(0.1)
print("%",end="")
sys.stdout.flush()


progress(50)


#doesnt affect actual execution
#based on events and consumption in background
#may be that actual process completes a bit earlier than progress shows 99%
#make an instance with number of elements in a loop
#in each iteration call the method current_progress


import time
from math import ceil
import os
import sys
from threading import Thread
class progress_bar(object):
def __init__(self,total_elements,length_bar=25):
self.length_bar=length_bar
self.total_elements=total_elements
self.singleweight=(float(1)/float(total_elements))*100
self.done=0
self.qt=[0]
self.call_count=0
t=Thread(target=self.display_progress)
t.start()
def current_progress(self):
self.done+=1
self.qt=[self.done]+self.qt
def display_progress(self):
while True:
try:
done=self.qt.pop()
except:
continue
else:
self.call_count+=1
self.progress=self.singleweight*done
fill=ceil(self.progress)
bar=int((fill*self.length_bar)/100)*"|"
bar="["+bar+str(fill)+"%"
barp=bar
for i in range(0,self.length_bar+3-(len(bar))):
barp=barp+"_"
barp=barp+"]"
if self.progress <= 100:
os.system("clear")
print("Progress:",barp, sep=' ', end='\n', file=sys.stdout, flush=True)
if self.call_count == self.total_elements:
break
else:
pass

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

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

已经有很多好的答案,但添加这个特定的基于@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)

受到许多不依赖包的答案的启发,我在这里分享我的实现。在任何循环中使用的函数都需要当前迭代数、迭代总数和初始时间。

import time
def simple_progress_bar(i: int, n: int, init_time: float):
avg_time = (time.time()-init_time)/(i+1)
percent = ((i+1)/(n))*100
print(
end=f"\r|{'='*(int(percent))+'>'+'.'*int(100-int(percent))}|| " + \
f"||Completion: {percent : 4.3f}% || \t "+ \
f"||Time elapsed: {avg_time*(i+1):4.3f} seconds || \t " + \
f"||Remaining time: {(avg_time*(n-(i+1))): 4.3f} seconds."
)
return






N = 325
t0 = time.time()
for k in range(N):
# stuff goes here #
time.sleep(0.0001)
# stuff goes here #
    

simple_progress_bar(k, N, t0)

pip install progressbar2

Progressbar Progressbar Progressbar Progressbar Progressbar < / p >

import os
import time
import progressbar


os.environ['PYCHARM_HOSTED'] = '1' # https://github.com/WoLpH/python-progressbar/issues/237


class COLOR: # https://stackoverflow.com/a/287944/11465149
YELLOW    = '\033[93m'
GREEN     = '\033[92m'
RED       = '\033[91m'
BOLD      = '\033[1m'
ENDC      = '\033[0m'


widgets=[
'FILE.JSON ',
COLOR.YELLOW          , progressbar.Percentage()                        , COLOR.ENDC,
COLOR.RED + COLOR.BOLD, progressbar.Bar(left=' ', marker='━', right=' '), COLOR.ENDC,
COLOR.YELLOW          , progressbar.Timer()                             , COLOR.ENDC
]


for i in progressbar.progressbar(range(100), widgets=widgets):
time.sleep(0.01)
if i == 99:
widgets[4] = COLOR.GREEN

使用enumerate(...progressbar(max_value=...) + this,以防你想用它作为下载进度条