本文实例讲述了 Python 显示进度条的方法, 是 Python 程序设计中非常实用的技巧分享给大家供大家参考具体方法如下:
首先, 进度条和一般的 print 区别在哪里呢?
答案就是 print 会输出一个 \ n, 也就是换行符, 这样光标移动到了下一行行首, 接着输出, 之前已经通过 stdout 输出的东西依旧保留, 而且保证我们在下面看到最新的输出结果
进度条不然, 我们必须再原地输出才能保证他是一个进度条, 否则换行了怎么还叫进度条?
最简单的办法就是, 再输出完毕后, 把光标移动到行首, 继续在那里输出更长的进度条即可实现, 新的更长的进度条把旧的短覆盖, 就形成了动画效果
可以想到那个转义符了吧, 那就是 \ r
转义符 r 就可以把光标移动到行首而不换行, 转义符 n 就把光标移动到行首并且换行
在 python 中, 输出 stdout(标准输出) 可以使用 sys.stdout.write
例如:
- #!/usr/bin/env python
- # -*- coding=utf-8 -*-
- #Using GPL v2
- #Author: ihipop@gmail.com
- ##2010-10-27 22:07
- """
- Usage:
- Just A Template
- """
- from __future__ import division
- import sys,time
- j = '#'
- if __name__ == '__main__':
- for i in range(1,61):
- j += '#'
- sys.stdout.write(str(int((i/60)*100))+'% ||'+j+'->'+"\r")
- sys.stdout.flush()
- time.sleep(0.5)
第二种思路是用转义符 \ b
转义符 \ b 是退格键, 也就是说把输出的光标往回退格子, 这样就可以不用 += 了, 例如:
- #!/usr/bin/env python
- # -*- coding=utf-8 -*-
- #Using GPL v2
- #Author: ihipop@gmail.com
- #2010-10-27 22:07
- """
- Usage:
- Just A Template
- """
- from __future__ import division
- import sys,time
- if __name__ == '__main__':
- for i in range(1,61):
- sys.stdout.write('#'+'->'+"\b\b")
- sys.stdout.flush()
- time.sleep(0.5)
光标回退 2 格, 写个 #再回退, 再写, 达到增长的目的了
不过写这么多似乎是废话, 在耳边常常听到一句话: 那就是不要重复造轮子实际上 python 有丰富发 lib 帮你实现这个东西, 你完全可以把心思放在逻辑开发上而不用注意这些小细节
下面要介绍的就是这个类 progressbar(http://code.google.com/p/python-progressbar/), 使用 easy_install 可以方便的安装这个类库, 其实就一个文件, 拿过来放到文件同一个目录下面也直接可以 import 过来
如下图所示:
下面就是基本使用举例:
- #!/usr/bin/env python
- # -*- coding=utf-8 -*-
- #Using GPL v2
- #Author: ihipop@gmail.com
- #2010-10-27 22:53
- """
- Usage:
- Just A Template
- """
- from __future__ import division
- import sys,time
- from progressbar import *
- total = 1000
- # 基本用法
- progress = ProgressBar()
- for i in progress(range(total)):
- time.sleep(0.01)
- pbar = ProgressBar().start()
- for i in range(1,1000):
- pbar.update(int((i/(total-1))*100))
- time.sleep(0.01)
- pbar.finish()
- # 高级用法
- widgets = ['Progress:', Percentage(), '', Bar(marker=RotatingMarker('>-=')),' ', ETA(),' ', FileTransferSpeed()]
- pbar = ProgressBar(widgets=widgets, maxval=10000000).start()
- for i in range(1000000):
- # do something
- pbar.update(10*i+1)
- time.sleep(0.0001)
- pbar.finish()
官方示例: http://code.google.com/p/python-progressbar/source/browse/progressbar/examples.py
- # coding:utf-8
- import sys
- import time
- from progressbar import AnimatedMarker, Bar, BouncingBar, Counter, ETA, \
- FileTransferSpeed, FormatLabel, Percentage, \
- ProgressBar, ReverseBar, RotatingMarker, \
- SimpleProgress, Timer
- examples = []
- def example(fn):
- try:
- name = 'Example %d' % int(fn.__name__[7:])
- except:
- name = fn.__name__
- def wrapped():
- try:
- sys.stdout.write('Running: %s\n' % name)
- fn()
- sys.stdout.write('\n')
- except KeyboardInterrupt:
- sys.stdout.write('\nSkipping example.\n\n')
- examples.append(wrapped)
- return wrapped
- @example
- def example0():
- pbar = ProgressBar(widgets=[Percentage(), Bar()], maxval=300).start()
- for i in range(300):
- time.sleep(0.01)
- pbar.update(i + 1)
- pbar.finish()
- @example
- def example1():
- widgets = ['Test:', Percentage(), '', Bar(marker=RotatingMarker()),' ', ETA(),' ', FileTransferSpeed()]
- pbar = ProgressBar(widgets=widgets, maxval=10000000).start()
- for i in range(1000000):
- # do something
- pbar.update(10 * i + 1)
- pbar.finish()
- @example
- def example2():
- class CrazyFileTransferSpeed(FileTransferSpeed):
- """It's bigger between 45 and 80 percent."""
- def update(self, pbar):
- if 45 < pbar.percentage() < 80:
- return 'Bigger Now' + FileTransferSpeed.update(self, pbar)
- else:
- return FileTransferSpeed.update(self, pbar)
- widgets = [CrazyFileTransferSpeed(), '<<<', Bar(), '>>>',
- Percentage(), ' ', ETA()]
- pbar = ProgressBar(widgets=widgets, maxval=10000000)
- # maybe do something
- pbar.start()
- for i in range(2000000):
- # do something
- pbar.update(5 * i + 1)
- pbar.finish()
- @example
- def example3():
- widgets = [Bar('>'), '', ETA(),' ', ReverseBar('<')]
- pbar = ProgressBar(widgets=widgets, maxval=10000000).start()
- for i in range(1000000):
- # do something
- pbar.update(10 * i + 1)
- pbar.finish()
- @example
- def example4():
- widgets = ['Test:', Percentage(), ' ',
- Bar(marker='0', left='[', right=']'),
- '', ETA(),' ', FileTransferSpeed()]
- pbar = ProgressBar(widgets=widgets, maxval=500)
- pbar.start()
- for i in range(100, 500 + 1, 50):
- time.sleep(0.2)
- pbar.update(i)
- pbar.finish()
- @example
- def example5():
- pbar = ProgressBar(widgets=[SimpleProgress()], maxval=17).start()
- for i in range(17):
- time.sleep(0.2)
- pbar.update(i + 1)
- pbar.finish()
- @example
- def example6():
- pbar = ProgressBar().start()
- for i in range(100):
- time.sleep(0.01)
- pbar.update(i + 1)
- pbar.finish()
- @example
- def example7():
- pbar = ProgressBar() # Progressbar can guess maxval automatically.
- for i in pbar(range(80)):
- time.sleep(0.01)
- @example
- def example8():
- pbar = ProgressBar(maxval=80) # Progressbar can't guess maxval.
- for i in pbar((i for i in range(80))):
- time.sleep(0.01)
- @example
- def example9():
- pbar = ProgressBar(widgets=['Working:', AnimatedMarker()])
- for i in pbar((i for i in range(50))):
- time.sleep(.08)
- @example
- def example10():
- widgets = ['Processed:', Counter(), 'lines (', Timer(), ')']
- pbar = ProgressBar(widgets=widgets)
- for i in pbar((i for i in range(150))):
- time.sleep(0.1)
- @example
- def example11():
- widgets = [FormatLabel('Processed: %(value)d lines (in: %(elapsed)s)')]
- pbar = ProgressBar(widgets=widgets)
- for i in pbar((i for i in range(150))):
- time.sleep(0.1)
- @example
- def example12():
- widgets = ['Balloon:', AnimatedMarker(markers='.oO<a href="http://www.jobbole.com/members/weiboyes8848">@*</a>')]
- pbar = ProgressBar(widgets=widgets)
- for i in pbar((i for i in range(24))):
- time.sleep(0.3)
- @example
- def example13():
- # You may need python 3.x to see this correctly
- try:
- widgets = ['Arrows:', AnimatedMarker(markers='')]
- pbar = ProgressBar(widgets=widgets)
- for i in pbar((i for i in range(24))):
- time.sleep(0.3)
- except UnicodeError:
- sys.stdout.write('Unicode error: skipping example')
- @example
- def example14():
- # You may need python 3.x to see this correctly
- try:
- widgets = ['Arrows:', AnimatedMarker(markers='')]
- pbar = ProgressBar(widgets=widgets)
- for i in pbar((i for i in range(24))):
- time.sleep(0.3)
- except UnicodeError:
- sys.stdout.write('Unicode error: skipping example')
- @example
- def example15():
- # You may need python 3.x to see this correctly
- try:
- widgets = ['Wheels:', AnimatedMarker(markers='')]
- pbar = ProgressBar(widgets=widgets)
- for i in pbar((i for i in range(24))):
- time.sleep(0.3)
- except UnicodeError:
- sys.stdout.write('Unicode error: skipping example')
- @example
- def example16():
- widgets = [FormatLabel('Bouncer: value %(value)d -'), BouncingBar()]
- pbar = ProgressBar(widgets=widgets)
- for i in pbar((i for i in range(180))):
- time.sleep(0.05)
- @example
- def example17():
- widgets = [FormatLabel('Animated Bouncer: value %(value)d -'),
- BouncingBar(marker=RotatingMarker())]
- pbar = ProgressBar(widgets=widgets)
- for i in pbar((i for i in range(180))):
- time.sleep(0.05)
- @example
- def example18():
- widgets = [Percentage(),
- '', Bar(),' ', ETA(),' ', AdaptiveETA()]
- pbar = ProgressBar(widgets=widgets, maxval=500)
- pbar.start()
- for i in range(500):
- time.sleep(0.01 + (i < 100) * 0.01 + (i > 400) * 0.9)
- pbar.update(i + 1)
- pbar.finish()
- @example
- def example19():
- pbar = ProgressBar()
- for i in pbar([]):
- pass
- pbar.finish()
- try:
- for example in examples:
- example()
- except KeyboardInterrupt:
- sys.stdout('\nQuitting examples.\n')
再发一个类:
- #!/usr/bin/env python
- # -*- coding=utf-8 -*-
- #Using GPL v2
- #Author: ihipop@gmail.com
- #2010-10-30 13:59
- """
- Usage:
- Just A Template
- """
- class progressbarClass:
- def __init__(self, finalcount, progresschar=None):
- import sys
- self.finalcount=finalcount
- self.blockcount=0
- #
- # See if caller passed me a character to use on the
- # progress bar (like "*"). If not use the block
- # character that makes it look like a real progress
- # bar.
- #
- if not progresschar: self.block=chr(178)
- else: self.block=progresschar
- #
- # Get pointer to sys.stdout so I can use the write/flush
- # methods to display the progress bar.
- #
- self.f=sys.stdout
- #
- # If the final count is zero, don't start the progress gauge
- #
- if not self.finalcount : return
- self.f.write('\n------------------- % Progress -------------------\n')
- return
- def progress(self, count):
- #
- # Make sure I don't try to go off the end (e.g. >100%)
- #
- count=min(count, self.finalcount)
- #
- # If finalcount is zero, I'm done
- #
- if self.finalcount:
- percentcomplete=int(round(100*count/self.finalcount))
- if percentcomplete < 1: percentcomplete=1
- else:
- percentcomplete=100
- #print "percentcomplete=",percentcomplete
- blockcount=int(percentcomplete/2)
- #print "blockcount=",blockcount
- if blockcount > self.blockcount:
- for i in range(self.blockcount,blockcount):
- self.f.write(self.block)
- self.f.flush()
- if percentcomplete == 100: self.f.write("\n")
- self.blockcount=blockcount
- return
- if __name__ == "__main__":
- from time import sleep
- pb=progressbarClass(8,"*")
- count=0
- while count<9:
- count+=1
- pb.progress(count)
- sleep(0.2)
另外, python cookbook 中 11.1 节也提供了一个不错的进度条类, 代码如下:
- import sys
- class progressbar(object):
- def __init__(self, finalcount, block_char='.'):
- self.finalcount = finalcount
- self.blockcount = 0
- self.block = block_char
- self.f = sys.stdout
- if not self.finalcount:
- return
- self.f.write('\n------------------ % Progress -------------------1\n')
- self.f.write('1 2 3 4 5 6 7 8 9 0\n')
- self.f.write('----0----0----0----0----0----0----0----0----0----0\n')
- def progress(self, count):
- count = min(count, self.finalcount)
- if self.finalcount:
- percentcomplete = int(round(100.0 * count / self.finalcount))
- if percentcomplete < 1:
- percentcomplete = 1
- else:
- percentcomplete = 100
- blockcount = int(percentcomplete // 2)
- if blockcount <= self.blockcount:
- return
- for i in range(self.blockcount, blockcount):
- self.f.write(self.block)
- self.f.flush()
- self.blockcount = blockcount
- if percentcomplete == 100:
- self.f.write("\n")
- if __name__ == "__main__":
- from time import sleep
- pb = progressbar(8, "*")
- for count in range(1, 9):
- pb.progress(count)
- sleep(0.2)
- pb = progressbar(100)
- pb.progress(20)
- sleep(0.3)
- pb.progress(47)
- sleep(0.3)
- pb.progress(90)
- sleep(0.3)
- pb.progress(100)
- print "testing 1:"
- pb = progressbar(1)
- pb.progress(1)
运行结果如下图所示:
希望本文所述对大家 Python 程序设计的学习有所帮助
http://blog.ihipop.info/2010/10/1736.html
来源: http://www.jqhtml.com/12393.html