小编典典

Python打印状态栏和百分比

all

要实现如下状态栏:

[==========                ]  45%
[================          ]  60%
[==========================] 100%

我想将此打印到标准输出,并不断刷新它,而不是打印到另一行。这个怎么做?


阅读 167

收藏
2022-03-10

共1个答案

小编典典

在此处输入图像描述

发布的答案都没有完全满足我的需求。所以我写了我自己的,如上图所示。我需要的功能:

  • 只传递步数和总步数,它完成了计算完成百分比的艰巨工作。
  • 使用 60 个字符,将它们分成 480 个“记号”,每个记号产生 0.21 %。如果没有刻度,每个字符将只有 1.67 %。
  • 支持添加标题。
  • 可选百分比在行尾完成。
  • 可变长度进度条,默认为 60 个字符或 480 个“记号”。
  • 设置进度条颜色,默认为绿色。

如何调用进度显示

调用进度显示非常简单。对于上面的示例.gif,该函数是使用以下方法调用的:

percent_complete(step, total_steps, title="Convert Markdown")

CSV 格式的 Stack Exchange 数据转储中大约total_steps有 2,500个。len(rows)step是当前行号,因为每个 Stack Exchange Markdown Q&A 都转换为 Kramdown(用于 GitHub Pages)。

Python代码

代码很简单,但比其他答案长一点:

def percent_complete(step, total_steps, bar_width=60, title="", print_perc=True):
    import sys

    # UTF-8 left blocks: 1, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8
    utf_8s = ["█", "▏", "▎", "▍", "▌", "▋", "▊", "█"]
    perc = 100 * float(step) / float(total_steps)
    max_ticks = bar_width * 8
    num_ticks = int(round(perc / 100 * max_ticks))
    full_ticks = num_ticks / 8      # Number of full blocks
    part_ticks = num_ticks % 8      # Size of partial block (array index)

    disp = bar = ""                 # Blank out variables
    bar += utf_8s[0] * full_ticks   # Add full blocks into Progress Bar

    # If part_ticks is zero, then no partial block, else append part char
    if part_ticks > 0:
        bar += utf_8s[part_ticks]

    # Pad Progress Bar with fill character
    bar += "▒" * int((max_ticks/8 - float(num_ticks)/8.0))

    if len(title) > 0:
        disp = title + ": "         # Optional title to progress display

    # Print progress bar in green: https://stackoverflow.com/a/21786287/6929343
    disp += "\x1b[0;32m"            # Color Green
    disp += bar                     # Progress bar to progress display
    disp += "\x1b[0m"               # Color Reset
    if print_perc:
        # If requested, append percentage complete to progress display
        if perc > 100.0:
            perc = 100.0            # Fix "100.04 %" rounding error
        disp += " {:6.2f}".format(perc) + " %"

    # Output to terminal repetitively over the same line using '\r'.
    sys.stdout.write("\r" + disp)
    sys.stdout.flush()

Python 代码注释

几点:

  • 问题中的[ .... ]括号占位符要求不是必需的,因为存在用于相同目的的填充字符。这节省了两个额外的字符,使进度条更宽。
  • bar_width可以根据屏幕宽度使用关键字参数。的默认值60似乎很适合大多数用途。
  • 调用函数时可以通过print_perc=True传递来覆盖关键字参数default 。print_perc=False这将允许更长的进度条。
  • 关键字参数默认为无title=""标题。如果您希望使用一次title="My Title":将自动添加到其中。
  • sys.stdout.write("\r")当你的程序完成后记得调用sys.stdout.flush()清除进度显示行。

概括

这个答案比其他答案长一点,但重要的是要注意它是一个完整的解决方案,而不是您需要添加更多代码的解决方案的一部分。

另一点是这个解决方案没有依赖项,也没有额外的安装。Python 支持 UTF-8 字符集,gnome-terminal无需额外设置。如果您使用的是 Python 2.7,则可能需要# -*- coding: utf-8 -*-在 shebang 之后。IE 作为程序的第二行。

该函数可以转换为具有单独initupdatepause(用于将调试内容打印到屏幕)resumeclose方法的类。

每当电视音量发生变化时,bash 脚本都会显示索尼电视音量libnotify-bin(弹出气泡消息)。如果您对 bash 进度条感兴趣,请访问 Stack Overflow 链接。

编辑 2022 年 1 月 30 日

  • 每个字符从 4 个刻度变为 8 个刻度。
  • 删除完整块之间的中断。
  • 添加颜色支持。
2022-03-10