当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?
例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?
请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。
现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。
当前回答
这里有一个非常简单的版本,如果你有一个循环,只是想了解迭代的进展,比如每一个点,比如说,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不是方案的一部分。使用你自己的迭代对象,不管你在循环什么。 这个版本没有提前告诉您总共有多少次迭代。
其他回答
你也可以用启迪。主要的优点是你可以在不覆盖进度条的同时记录日志。
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()
如果你的工作不能被分解成可测量的块,你可以在一个新的线程中调用你的函数,并记录它所花费的时间:
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"
显然,您可以根据需要提高计时精度。
对于类似的应用程序(在循环中跟踪进度),我简单地使用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
我喜欢这一页。
从简单的示例开始,然后转移到多线程版本。开箱即用。不需要第三方软件包。
代码看起来像这样:
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
这是创建进度条的简单方法
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)