python的进度条实现

进度条最主要的问题就是所有字符全部在同一行,而且可以修改。然而当执行print语句的时候,python会在打印完这个语句的同时,在结尾加上换行‘ ’,这就导致在控制台下一旦被print之后就无法修改了。

我们需要使用的是来自sys.stdout.write()函数,这个函数会在控制台输出这个字符串的同时不加上任何结尾,这就意味着这个输出还没有完全结束。通过sys.stdout.flush()函数可以把输出暂时打印在控制台中(造成print的假象)。那么我们用‘ ’来回到行首。一切看起来那么简单了。

也就是说:打印字符串的时候,没有加上' ',同时让光标回到行首,再把当前缓冲区显示出来,也就好像是print了一样,但是这时候光标还在原来位置。

举个例子:

import sys, time
for i in range(10):
    sys.stdout.write('{0}/10
'.format(i + 1))
    sys.stdout.flush()
    time.sleep(1)

在终端下执行这段代码就会得到简单的进度效果。

接下来需要解决两个问题:

一、清空缓冲区:

当新的字符串比之前短的时候会出现问题,如下:

import sys, time
for i in range(10):
    sys.stdout.write(str(i) * (10 - i) + '
')
    sys.stdout.flush()
    time.sleep(1)

运行后会发现,结果跟期望的不一样。

其实是因为已经被flush出去的字符并不会主动清空,所以只有新写入的被修改了。针对这点,我目前的解决方案是先输出一波空格,把之前的字符串冲掉,然后重写:

import sys, time
for i in range(10):
    sys.stdout.write(str(i) * (10 - i) + '
')
    sys.stdout.flush()
    time.sleep(1)

二、固定底边输出:

有时候我们希望在进度条加载的同时,还有一些其他输出。不妨在刷新掉上一次输出之后输出所需输出的字符串,然后在假输出进度条。如下:

import sys, time
for i in range(10):
    sys.stdout.write(' ' * 10 + '
')
    sys.stdout.flush()
    print(i)
    sys.stdout.write(str(i) * (10 - i) + '
')
    sys.stdout.flush()
    time.sleep(1)

以后也可以给出一个自己实现的类来打印进度条:

class Process(object):
    def __init__(self, id, wide=20):
        self.id = id
        self.wide = wide

    def log(self, line):
        info = self.id*line + '{0}%'.format(int(line/self.wide*100)) + '
'
        sys.stdout.write(info)
        sys.stdout.flush()
        time.sleep(0.5)

obj = Process('>>')
for i in range(20):
    obj.log(i)
进度条
 1 import sys, time
 2 
 3 
 4 class ProgressBar:
 5     def __init__(self, count=0, total=0, width=50):
 6         self.count = count
 7         self.total = total
 8         self.width = width
 9 
10     def move(self):
11         self.count += 1
12 
13     def log(self, s):
14         sys.stdout.write(' ' * (self.width + 9) + '
')
15         sys.stdout.flush()
16         print(s)
17         progress = self.width * self.count / self.total
18         sys.stdout.write('{0:3}/{1:3}: '.format(self.count, self.total))
19         sys.stdout.write('#' * int(progress) + '-' * int(self.width - progress) + '
')
20         if progress == self.
21             sys.stdout.write('
')
22         sys.stdout.flush()
23 
24 
25 bar = ProgressBar(total=10)
26 for i in range(10):
27     bar.move()
28     bar.log('We have arrived at: ' + str(i + 1))
29     time.sleep(1)
进度条二
原文地址:https://www.cnblogs.com/caibao666/p/6805799.html