Python实现控制台进度条功能


Posted in Python onJanuary 04, 2016

本文实例讲述了Python显示进度条的方法,是Python程序设计中非常实用的技巧。分享给大家供大家参考。具体方法如下:

首先,进度条和一般的print区别在哪里呢?

答案就是print会输出一个\n,也就是换行符,这样光标移动到了下一行行首,接着输出,之前已经通过stdout输出的东西依旧保留,而且保证我们在下面看到最新的输出结果。

进度条不然,我们必须再原地输出才能保证他是一个进度条,否则换行了怎么还叫进度条?

最简单的办法就是,再输出完毕后,把光标移动到行首,继续在那里输出更长的进度条即可实现,新的更长的进度条把旧的短覆盖,就形成了动画效果。

可以想到那个转义符了吧,那就是\ r。

转义符r就可以把光标移动到行首而不换行,转义符n就把光标移动到行首并且换行。

在python中,输出stdout(标准输出)可以使用sys.stdout.write
例如:

Python

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2
"""
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)
print

第二种思路是用转义符\b
转义符\b是退格键,也就是说把输出的光标往回退格子,这样就可以不用+=了,例如:

Python

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2
"""
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)
print

光标回退2格,写个#再回退,再写,达到增长的目的了

不过写这么多似乎是废话,在耳边常常听到一句话:那就是不要重复造轮子。实际上python有丰富发lib帮你实现这个东西,你完全可以把心思放在逻辑开发上而不用注意这些小细节

下面要介绍的就是这个类“progressbar”(http://code.google.com/p/python-progressbar/),使用easy_install可以方便的安装这个类库,其实就一个文件,拿过来放到文件同一个目录下面也直接可以import过来

如下图所示:

Python实现控制台进度条功能

下面就是基本使用举例:

Python

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2

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

Python

# 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')

再发一个类:

Python

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#Using GPL v2
"""
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节也提供了一个不错的进度条类,代码如下:

Python

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实现控制台进度条功能

希望本文所述对大家Python程序设计的学习有所帮助。

Python 相关文章推荐
浅析Python基础-流程控制
Mar 18 Python
Python实现二叉树结构与进行二叉树遍历的方法详解
May 24 Python
Python编程判断这天是这一年第几天的方法示例
Apr 18 Python
python实现kNN算法
Dec 20 Python
详解Python3 中hasattr()、getattr()、setattr()、delattr()函数及示例代码数
Apr 18 Python
python email smtplib模块发送邮件代码实例
Apr 26 Python
Python使用numpy模块创建数组操作示例
Jun 20 Python
python3+requests接口自动化session操作方法
Oct 13 Python
pygame游戏之旅 游戏中添加显示文字
Nov 20 Python
在Pycharm中将pyinstaller加入External Tools的方法
Jan 16 Python
python输入多行字符串的方法总结
Jul 02 Python
使用Pytorch训练two-head网络的操作
May 28 Python
python实现网站的模拟登录
Jan 04 #Python
Python实现简单的文件传输与MySQL备份的脚本分享
Jan 03 #Python
简单介绍Python中的几种数据类型
Jan 02 #Python
简单实现python爬虫功能
Dec 31 #Python
python实现颜色空间转换程序(Tkinter)
Dec 31 #Python
基于python的Tkinter实现一个简易计算器
Dec 31 #Python
python实现爬虫统计学校BBS男女比例之数据处理(三)
Dec 31 #Python
You might like
不用数据库的多用户文件自由上传投票系统(1)
2006/10/09 PHP
require(),include(),require_once()和include_once()区别
2008/03/27 PHP
php获取参数的几种方法总结
2014/02/18 PHP
Ajax请求PHP后台接口返回信息的实例代码
2018/08/21 PHP
setTimeout与setInterval在不同浏览器下的差异
2010/01/24 Javascript
Jquery Ajax xmlhttp请求成功问题
2015/02/04 Javascript
javascript实现点击按钮让DIV层弹性移动的方法
2015/02/24 Javascript
Bootstrap CSS组件之下拉菜单(dropdown)
2016/12/17 Javascript
JS生成随机打乱数组的方法示例
2017/12/23 Javascript
Node.js Buffer模块功能及常用方法实例分析
2019/01/05 Javascript
使用layui的router来进行传参的实现方法
2019/09/06 Javascript
Vue开发中遇到的跨域问题及解决方法
2020/02/11 Javascript
vue-quill-editor插入图片路径太长问题解决方法
2021/01/08 Vue.js
[38:32]完美世界DOTA2联赛循环赛 Forest vs DM 第二场 11.06
2020/11/06 DOTA
Python出现segfault错误解决方法
2016/04/16 Python
Python实现SSH远程登陆,并执行命令的方法(分享)
2017/05/08 Python
python之从文件读取数据到list的实例讲解
2018/04/19 Python
python+logging+yaml实现日志分割
2019/07/22 Python
Python文本文件的合并操作方法代码实例
2020/03/31 Python
python列表的逆序遍历实现
2020/04/20 Python
利用Python实现某OA系统的自动定位功能
2020/05/27 Python
python交互模式基础知识点学习
2020/06/18 Python
keras输出预测值和真实值方式
2020/06/27 Python
python读取excel进行遍历/xlrd模块操作
2020/07/12 Python
Python实现迪杰斯特拉算法过程解析
2020/09/18 Python
Python实现自动整理文件的脚本
2020/12/17 Python
CSS3 三维变形实现立体方块特效源码
2016/12/15 HTML / CSS
css3边框_动力节点Java学院整理
2017/07/11 HTML / CSS
css3实现背景模糊的三种方式(小结)
2020/05/15 HTML / CSS
Perfume’s Club美国官网:西班牙第一家在线美容店
2020/06/10 全球购物
简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
2012/04/17 面试题
教师师德反思材料
2014/02/15 职场文书
2014厂务公开实施方案
2014/02/17 职场文书
个人贷款授权委托书样本
2014/10/07 职场文书
python实现批量移动文件
2021/04/05 Python
虚拟机linux端mysql数据库无法远程访问的解决办法
2021/05/26 MySQL