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

0 投票
3 回答
4017 浏览
提问于 2025-04-17 19:30

我写了下面的代码(在代码审查中已经检查过),目的是在 Python 2.7 中打印一个进度条(顺便说一下,我知道 Python 中有一个 进度条模块)。

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()

我希望在我的开发环境中使用这个进度条(比如 Pyscripter、PyCharm 等),还有在命令提示符下使用。当我在命令提示符下运行时,我遇到了两个问题,我不太明白该怎么解决。

在这里输入图片描述

  1. 首先,进度条会打印出限制值(我用了 100s)。
  2. 其次,进度条会一个接一个地打印出所有的条。我希望在循环中只显示一个进度条,并且这个条会逐渐增加。

3 个回答

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)的标准输出环境中是行不通的

像 Eclipse、PyCharm 等工具会直接读取标准输出,并把变化原样打印到控制台上。

2

问题 1:

你的终端窗口宽度不到 100 个字符,这就是为什么你的进度条看起来超出了限制。其实它只是把输出在 80 个字符处换行了(这是标准的宽度,也是 Windows 控制台的宽度)。

为了避免换行,可以尝试:

sys.stdout.write("|%-50s| %d%%" % ('#' *int(self._pct/2), self._pct) + '\n')
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%% 来格式化百分比,这样它就能保持右对齐,一直都是这样。

撰写回答