【问题标题】:fixing a Python progress bar in Command Prompt修复命令提示符中的 Python 进度条
【发布时间】:2013-03-18 12:42:25
【问题描述】:

为了在 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 等)和命令提示符中使用这个进度条。当我使用命令提示符运行时,我遇到以下两个问题,我无法理解如何解决。

  1. 首先,进度条打印出限制(我用的是100s)
  2. 其次,进度条一个接一个地打印所有条。我希望 在循环过程中只有一根柱子增加

【问题讨论】:

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


    【解决方案1】:

    问题 1:

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

    为避免包装,请尝试:

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

    【讨论】:

    • 您可以删除“\n”(避免打印换行符),在开头添加“\r”(在开头打印),并使用%3d%%(保持相同的宽度) .
    • 这可能不适用于所有可能的终端类型。 (事实上​​,没有任何方法可以保证适用于所有终端类型)。无论如何感谢这个有用的补充。
    【解决方案2】:

    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%% 填充百分比,使其始终保持右对齐。

    【讨论】:

    • 嘿,谢谢。我尝试了您的解决方案,但在 10% 之后,我在命令提示符下遇到了同样的问题
    • Chmulling 只需将 74 更改为 73! :) (但 100% 有一点瑕疵)
    • Chmulling 与 72 在 100% 处有一个空白空间:P
    【解决方案3】:

    问题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 等正在读取标准输出管道并将更改原始打印到控制台视图中。

    【讨论】:

    • 感谢 Colin,您是否建议更改“def display(self):”以打印递增的进度?
    • 嗯,我会检查console logs 是否还有其他“进步”方式,比如 PyCham,甚至还有 Tail。也许启动 GUI 进度条也会对您有所帮助。我可以想象弹出一个简单的、不可调整大小的进度迷你应用程序(wxPython 或 Tcl/Tkinter)。
    猜你喜欢
    • 2018-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-08
    • 2014-11-22
    • 2019-09-18
    • 2016-04-23
    • 2013-09-11
    相关资源
    最近更新 更多