【问题标题】:My program is not updating its output [duplicate]我的程序没有更新它的输出[重复]
【发布时间】:2016-12-22 13:47:53
【问题描述】:

我正在尝试制作一种简单的进度条,每半秒百分比就会上升;输出不断自我更新。为此,我尝试使用 '\r' 参数,但代码只是忽略它并一遍又一遍地打印进度条,直到达到 100%。

代码如下:

import time
def progressBar(value, endvalue, bar_length=20):
    while value <= endvalue:
        percent = float(value) / endvalue
        arrow = '-' * int(round(percent * bar_length)-1) + '>'
        spaces = ' ' * (bar_length - len(arrow))
        print("\rPercent: [{0}] {1}%".format(arrow + spaces, int(round(percent * 100))))
        value+=1
        time.sleep(0.5)

progressBar(1, 100)

输出:

Percent: [>                   ] 1%

Percent: [>                   ] 2%

Percent: [>                   ] 3%

Percent: [>                   ] 4%

Percent: [>                   ] 5%

Percent: [>                   ] 6%

Percent: [>                   ] 7%

Percent: [->                  ] 8%

Percent: [->                  ] 9%

Percent: [->                  ] 10%

Percent: [->                  ] 11%

等等等等。

谁能告诉我这里有什么问题?

【问题讨论】:

  • 对于箭头变量,您缺少与 100 的乘法
  • print() 将在要打印的消息之后附加换行符。试试print("Percent: ...", end='\r')
  • 它只是打印所有内容,就像我写的一样 (end=' ')
  • 可能是因为你使用的IDE,在控制台中测试一下。
  • 在控制台上试过,一样

标签: python


【解决方案1】:

你需要告诉print()不要打印换行符:

print("\rPercent: [{0}] {1}%".format(arrow + spaces, int(round(percent * 100))),
      end="")

end 设置为空字符串会替换默认写入的\n

您可能希望在 while 循环完成后添加 print() 以添加显式换行符。

只有end=""的演示:

您可能需要添加flush=True 以确保不存在缓冲区问题(一些终端缓冲区在刷新之前等待换行符):

print("\rPercent: [{0}] {1}%".format(arrow + spaces, int(round(percent * 100))),
      end="", flush=True)

或者,使用sys.stdout.write()sys.stdout.flush()

sys.stdout.write("\rPercent: [{0}] {1}%".format(arrow + spaces, int(round(percent * 100))))
sys.stdout.flush()

print 无论如何都会对sys.stdout.write() 产生完全相同的调用。

【讨论】:

  • 它给了我这个:`百分比:[>] 1% 百分比:[>] 2% 百分比:[>] 3% 百分比:[>] 4% 百分比:[>] 5% 百分比: [> ] 6% 百分比: [> ] 7% 百分比: [-> ] 8% 百分比: [-> ] 9% 百分比: [-> ] 10% 百分比: [-> ] 11% 百分比: [-> ] 12% 百分比:[--> ] 13% 百分比:[--> ] 14% 百分比:[--> `
  • 它以某种方式忽略了我的 '\r'
  • @DanielEngel:你用的是什么控制台? \r 需要控制台或终端支持。例如,它不适用于许多 IDE。
  • 在终端中它甚至不为我打开
  • @DanielEngel:如果您使用的是 Python 2,我建议您在脚本顶部使用 from __future__ import print_function。或者,删除() 括号并使用print "...".format(...),(在要打印的字符串后添加一个逗号)或使用import sys 然后sys.stdout.write("...".format(...)) 直接写入标准输出而无需换行。
【解决方案2】:

现有的进度条实现(也在其他应用程序中,例如 MATLAB)竭尽全力跟踪它们在每次更新时发送到输出流的字符数,以便它们可以发送尽可能多的退格字符 \b “擦除”这些字符。 (这取决于您的平台/控制台以及脚本的调用方式。)

\r 不像您在控制台的输出流中所期望的那样工作。

【讨论】:

  • \r大多数终端中运行良好。然而,并非在所有控制台(IDE 输出窗口)中。
  • 那么我应该使用什么其他方式才不会令人困惑?
  • @MartijnPieters 你当然是对的(尽管我不确定我们是否可以就其工作的终端之间的比率做出可靠的定量陈述)。考虑到不支持 \r 所需的终端数量,在编写一段代码时期望它不支持会更安全。即使这样,例如在 Windows 7 上通过批处理运行脚本,也无法正确处理通过多行进度条的“退格”。
  • @PierreSchroeder:对 Mercurial 来说已经足够了; progress bar code uses \r.
【解决方案3】:

我已经在OSX 10.11.6中安装了python 2.7.10,下面的代码可能会满足你在终端中的要求

import time
import sys
def progressBar(value, endvalue, bar_length=20):
    while value <= endvalue:
        percent = float(value) / endvalue
        arrow = '-' * int(round(percent * bar_length)-1) + '>'
        spaces = ' ' * (bar_length - len(arrow))
        print("\rPercent: [{0}] {1}%".format(arrow + spaces, int(round(percent * 100))))
        sys.stdout.write("\033[F")
        value+=1
        time.sleep(0.5)

progressBar(1, 100)

【讨论】:

  • 抱歉,控制台的输出还是一样
猜你喜欢
  • 2017-09-27
  • 1970-01-01
  • 2019-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多