Python中如何寫控制檯進度條的整理

進度條和通常的print區別在哪裏呢?html

答案就是print會輸出一個\n,也就是換行符,這樣光標移動到了下一行行首,接着輸出,以前已經經過stdout輸出的東西依舊保留,並且保證咱們在下面看到最新的輸出結果。python

進度條否則,咱們必須再原地輸出才能保證他是一個進度條,不然換行了怎麼還叫進度條?動畫

最簡單的辦法就是,再輸出完畢後,把光標移動到行首,繼續在那裏輸出更長的進度條便可實現,新的更長的進度條把舊的短覆蓋,就造成了動畫效果。google

能夠想到那個轉義符了吧,那就是 \r。spa

轉義符\r就能夠把光標移動到行首而不換行,轉義符\n就把光標移動到行首而且換行。code

在python中,輸出stdout(標準輸出)能夠使用sys.stdout.write
例如:htm

#!/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)
print

 

 

第二種思路是用轉義符\b
轉義符\b是退格鍵,也就是說把輸出的光標往回退格子,這樣就能夠不用+=了,例如:ip

 

#!/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)
print

 

 

光標回退2格,寫個#再回退,再寫,達到增加的目的了utf-8

 

不過寫這麼多彷佛是廢話,在耳邊經常聽到一句話:那就是不要重複造輪子。實際上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

再發一個類:

 

#!/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)
相關文章
相關標籤/搜索