在命令提示符中修复Python进度条

时间:2013-03-18 12:42:25

标签: python performance optimization progress-bar command-prompt

我已经编写了以下代码(在代码审查中查看),以便在python 2.7中打印进度条(PS:我知道Python中有progressbar module

from __future__ import division
import sys

class Progress(object):
    def __init__(self, maxval):
        self._pct = 0
        self.maxval = maxval

    def update(self, value):
        pct = int((value / self.maxval) * 100.0)
        if self._pct != pct:
            self._pct = pct
            self.display()

    def start(self):
        self.update(0)

    def finish(self):
        self.update(self.maxval)

    def display(self):
        sys.stdout.write("|%-100s| %d%%" % ('#' *self._pct, self._pct) + '\n')
        sys.stdout.flush()

# test
import time

toolbar_width = 300
pbar = Progress(toolbar_width)
pbar.start()
for i in xrange(toolbar_width):
    time.sleep(0.1) # do real work here
    pbar.update(i)
pbar.finish()

我希望在我的IDE(例如:Pyscripet,PyCharm等)和命令提示符中使用此进度条。当我用命令提示符运行时,我有以下两个问题,我无法理解我如何解决。

enter image description here

  1. 首先,进度条打印出限制(我用了100秒)
  2. 第二,进度条一个接一个地打印所有栏。我希望 在循环期间只有一个增加的栏

3 个答案:

答案 0 :(得分:2)

问题1:

您的终端窗口宽度小于100个字符,这就是您的进度条似乎打印超出限制的原因,而它只是将输出包装为80个字符(这是Windows上的标准和控制台宽度)。

为避免包装,请尝试:

sys.stdout.write("|%-50s| %d%%" % ('#' *int(self._pct/2), self._pct) + '\n')

答案 1 :(得分:1)

问题2 :如果要在一行中显示不断增加的进度控制栏,则必须重置光标位置,通过编写回车符可以完成的操作登录stdout

import sys, time

for x in range(10):
    sys.stdout.write((x+1) * '#')
    time.sleep(1)
    sys.stdout.write("\r") # !!! carriage return sign under Windows !!!

print("Fine")

但我很遗憾地说:主要是在IDE stdout封装环境中不起作用

Eclipse,PyCharm等正在读取stdout管道并将原始打印更改为控制台视图。

答案 2 :(得分:1)

1。由于线路长度可能会缠绕,该终端看起来比100个字符宽。如果你想假设80个字符(大多数控制台默认使用),我认为你有其他东西的7个字符,所以进度条使用73个字符的宽度。

    sys.stdout.write("|%-73s| %3d%%" % ('#' * int(self._pct*.73), self._pct) + '\n')

2. 要保持同一条线,请使用sys.stdout.write,并且最后不要包含换行符。然后在每行的开头添加\r以返回到开头。

        sys.stdout.write("\r|%-73s| %3d%%" % ('#' * int(self._pct*.73), self._pct))

您还可以使用%3d%%来填充百分比,因此它始终保持正确对齐。