其他打印报表中的进度条不起作用 - 找不到有用的进度条

问题描述 投票:0回答:1

简介(乘坐星际办公椅)

我有一个程序,如果程序正在运行,使用进度条显示最终用户。这应该告诉最终用户他们需要等待多长时间以及程序是否仍然有效。在阅读这个有趣的堆栈溢出线程之后出现了这个问题:Text Progress Bar in the Console

问题/挑战

第一个问题是进度条目前仅在循环中工作,只打印出范围内的数字。这没用。为什么有人想要一个带有进度条的程序,它只显示单个循环的进度,而不是程序的其余部分正在做什么。

第二个问题是当我有进度条的其他打印语句时,突然有多个进度条打印到命令提示符而不是单个进度条,它似乎为每个进度条更新设置动画。

如何将进度条始终位于终端的底部,并在其上方显示其他打印语句?

另一个挑战是我使用的是Windows 7操作系统(OS)。

请查看我为您提供的以下示例代码:

import sys
import time
import threading



def progress_bar(progress):
    sys.stdout.write('\r[{0}] {1}'.format('#' * int(progress/10 * 10), progress))


def doThis():
    for i in range(10):
        print("Doing this.")

def doThat():
    for i in range(3):
        print("Doing that.")

def wrapUp():
    total = 2+ 2
    print("Total found")
    return total


if __name__ == "__main__":

  print("Starting in main...")
  progress_bar(1)
  print("\nOther print statement here.")
  print("Nice day, expensive day.")
  progress_bar(3)

  doThis()
  progress_bar(4)
  doThat()
  progress_bar(5)
  doThis()
  doThat()
  progress_bar(6)
  progress_bar(7)
  doThat()
  doThat()
  progress_bar(8)
  wrapUp()
  progress_bar(9)
  progress_bar(10)

程序打印的内容

   Starting in main...
[#] 1
Other print statement here.
Nice day, expensive day.
[###] 3Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
[####] 4Doing that.
Doing that.
Doing that.
[#####] 5Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing that.
Doing that.
Doing that.
[#######] 7Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
[########] 8Total found
[##########] 10
python python-3.x windows progress-bar
1个回答
2
投票

你必须做三件事:

  • 将进度条状态存储在单独的对象中,您可以调用方法来更新不同循环中的条状态。
  • 打印进度条时,请确保不打印换行符
  • 打印控制台输出时,首先清除当前行,然后在打印后重新绘制条。

你覆盖前两个,有些,但不是第三个。最好将控制台的控制权封装在管理进度条的类中,这样它就可以在一个位置处理清除,打印和重新显示:

import builtins
import math
import sys
import threading

class ProgressConsole:
    def __init__(self, size, width=80, output=sys.stdout):
        self.size = size
        self.width = width
        self.current = 0
        self.output = output
        # [...] and space take 3 characters, plus max width of size (log10 + 1)
        self._bar_size = width - 4 - int(math.log10(size))
        self._bar_step = self._bar_size / self.size
        self._lock = threading.Lock()

    def print(self, *message):
        with self._lock:
            self._clear()
            builtins.print(*message, file=self.output)
            self._display()

    def increment(self, step=1):
        with self._lock:
            self.current = min(self.current + step, self.size)
            self._display()

    def _clear(self):
        self.output.write('\r')
        self.output.write(' ' * self.width)
        self.output.write('\r')

    def _display(self):
        bar = '#' * int(round(self._bar_step * self.current))
        blank = ' ' * (self._bar_size - len(bar))
        self.output.write(f"\r[{bar}{blank}] {self.current}")

我包含一个线程锁,因为您的示例代码导入了threading,所以我假设您希望能够在这样的环境中使用它。

上面的类使用固定宽度作为进度条,并通过写回一系列空格来擦除它,然后返回到\r最左边的列。

我还将条形图固定为宽度,使其从左到右填充,而不是在屏幕上生长。

然后确保你'打印'到这个对象:

if __name__ == "__main__":
    progress_bar = ProgressConsole(10)
    print = progress_bar.print  # replace built-in with our own version

    print("Starting in main...")
    progress_bar.increment()
    print("\nOther print statement here.")
    print("Nice day, expensive day.")
    progress_bar.increment(2)

    doThis()
    progress_bar.increment()
    doThat()
    progress_bar.increment()
    doThis()
    doThat()
    progress_bar.increment(2)
    doThat()
    doThat()
    progress_bar.increment()
    wrapUp()
    progress_bar.increment(2)

上面的最终输出是:

Starting in main...

Other print statement here.
Nice day, expensive day.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing that.
Doing that.
Doing that.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
Total found
[###########################################################################] 10

插入几个随机睡眠后,它在运行时看起来像这样:

progressbar running

© www.soinside.com 2019 - 2024. All rights reserved.