Python打印状态栏和百分比

Sta*_*tan 140 python

要实现如下状态栏:

[==========                ]  45%
[================          ]  60%
[==========================] 100%
Run Code Online (Sandbox Code Playgroud)

我希望将它打印到stdout,并保持刷新,而不是打印到另一行.这该怎么做?

Mar*_*off 233

'\r'字符(回车)重置光标移到行的开头,并允许你写在什么以前就行了.

from time import sleep
import sys

for i in range(21):
    sys.stdout.write('\r')
    # the exact output you're looking for:
    sys.stdout.write("[%-20s] %d%%" % ('='*i, 5*i))
    sys.stdout.flush()
    sleep(0.25)
Run Code Online (Sandbox Code Playgroud)

我不是100%确定它是否可以在所有系统中完全移植,但它至少可以在Linux和OSX上运行.

  • 如上所述,代码并未明确如何使其适应您迭代的任何大小(而不是21).我会让`n = 21`,用`range(n)`替换`range(21)`,然后在循环中添加`j =(i + 1)/ n`,并用这个替换`write`语句稍微修改:`sys.stdout.write("[% - 20s]%d %%"%('='*int(20*j),100*j))`.现在你需要做的唯一改变是在循环之前`n = 21`(更可能是`n = len(iterable)`),然后枚举可迭代对象.我推荐这个编辑,但它被拒绝了; 显然功能"偏离了帖子的原始意图". (12认同)
  • 这比标记的答案要好,因为它也适用于Python 3. (5认同)
  • 自适应任意大小的n, `sys.stdout.write("[{:{}}] {:.1f}%".format("="*i, n-1, (100/(n-1)) *i)))`,仅限 Python 3 (2认同)
  • 什么是“%-20s”? (2认同)
  • @ StevenC.Howell为什么不将其作为马克的答案发布?这是另一个版本,准备工作非常有帮助 (2认同)

ick*_*fay 128

有一个Python模块可以从PyPI调用progressbar,它实现了这样的功能.如果您不介意添加依赖项,那么这是一个很好的解决方案.否则,请使用其他答案之一.

一个如何使用它的简单示例:

import progressbar
from time import sleep
bar = progressbar.ProgressBar(maxval=20, \
    widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()])
bar.start()
for i in xrange(20):
    bar.update(i+1)
    sleep(0.1)
bar.finish()
Run Code Online (Sandbox Code Playgroud)

要安装它,您可以使用easy_install progressbar,或者pip install progressbar如果您更喜欢pip.

  • 也许这个例子需要像`bar.start()`这样的东西? (8认同)
  • 安装:`sudo -H pip install progressbar2`. (4认同)
  • 不能在我的机器上工作 - 需要添加`bar.start()` (2认同)
  • 此模块已超过 2 年未更新。不要将它用于新软件! (2认同)

omi*_*ron 78

我找到了有用的库tqdm(https://github.com/tqdm/tqdm/,以前:https://github.com/noamraph/tqdm).它会自动估计完成时间,并可用作迭代器.

用法:

import tqdm
import time

for i in tqdm.tqdm(range(1000)):
    time.sleep(0.01)
    # or other long operations
Run Code Online (Sandbox Code Playgroud)

结果是:

|####------| 450/1000  45% [elapsed: 00:04 left: 00:05, 99.15 iters/sec]
Run Code Online (Sandbox Code Playgroud)

tqdm 可以包装任何可迭代的.

  • 这是最简单的解决方案 (6认同)
  • 一个新的开发团队正在[tqdm项目现在维护](https://github.com/tqdm/tqdm/). (4认同)
  • 哇,这个 tqdm 真是太棒了,而且很容易使用 :) 。 (3认同)
  • 它也与Anaconda distrib捆绑在一起!(至少适用于python 3.5及以上版本) (2认同)

Mat*_*hen 21

你可以使用\r(回车).演示:

import sys
total = 10000000
point = total / 100
increment = total / 20
for i in xrange(total):
    if(i % (5 * point) == 0):
        sys.stdout.write("\r[" + "=" * (i / increment) +  " " * ((total - i)/ increment) + "]" +  str(i / point) + "%")
        sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)


Jac*_*CUI 18

在这里,您可以使用以下代码作为函数:

def drawProgressBar(percent, barLen = 20):
    sys.stdout.write("\r")
    progress = ""
    for i in range(barLen):
        if i < int(barLen * percent):
            progress += "="
        else:
            progress += " "
    sys.stdout.write("[ %s ] %.2f%%" % (progress, percent * 100))
    sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

使用.format:

def drawProgressBar(percent, barLen = 20):
    # percent float from 0 to 1. 
    sys.stdout.write("\r")
    sys.stdout.write("[{:<{}}] {:.0f}%".format("=" * int(barLen * percent), barLen, percent * 100))
    sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)


Win*_*nix 14

在此输入图像描述

\n

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

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

如何调用进度显示

\n

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

\n
percent_complete(step, total_steps, title="Convert Markdown")\n
Run Code Online (Sandbox Code Playgroud)\n

CSV 格式的 Stack Exchange 数据转储大约total_steps有 2,500 个。len(rows)step是每个 Stack Exchange Markdown 问答转换为 Kramdown(对于 GitHub Pages)时的当前行号。

\n

Python代码

\n

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

\n
def percent_complete(step, total_steps, bar_width=60, title="", print_perc=True):\n    import sys\n\n    # UTF-8 left blocks: 1, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8\n    utf_8s = ["\xe2\x96\x88", "\xe2\x96\x8f", "\xe2\x96\x8e", "\xe2\x96\x8d", "\xe2\x96\x8c", "\xe2\x96\x8b", "\xe2\x96\x8a", "\xe2\x96\x88"]\n    perc = 100 * float(step) / float(total_steps)\n    max_ticks = bar_width * 8\n    num_ticks = int(round(perc / 100 * max_ticks))\n    full_ticks = num_ticks / 8      # Number of full blocks\n    part_ticks = num_ticks % 8      # Size of partial block (array index)\n    \n    disp = bar = ""                 # Blank out variables\n    bar += utf_8s[0] * int(full_ticks)  # Add full blocks into Progress Bar\n    \n    # If part_ticks is zero, then no partial block, else append part char\n    if part_ticks > 0:\n        bar += utf_8s[part_ticks]\n    \n    # Pad Progress Bar with fill character\n    bar += "\xe2\x96\x92" * int((max_ticks/8 - float(num_ticks)/8.0))\n    \n    if len(title) > 0:\n        disp = title + ": "         # Optional title to progress display\n    \n    # Print progress bar in green: https://stackoverflow.com/a/21786287/6929343\n    disp += "\\x1b[0;32m"            # Color Green\n    disp += bar                     # Progress bar to progress display\n    disp += "\\x1b[0m"               # Color Reset\n    if print_perc:\n        # If requested, append percentage complete to progress display\n        if perc > 100.0:\n            perc = 100.0            # Fix "100.04 %" rounding error\n        disp += " {:6.2f}".format(perc) + " %"\n    \n    # Output to terminal repetitively over the same line using \'\\r\'.\n    sys.stdout.write("\\r" + disp)\n    sys.stdout.flush()\n
Run Code Online (Sandbox Code Playgroud)\n

Python 代码注释

\n

几点:

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

概括

\n

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

\n

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

\n

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

\n

该函数是从 bash 脚本转换而来的:

\n\n

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

\n

2022 年 1 月 30 日编辑

\n
    \n
  • 每个字符从 4 个刻度更改为 8 个刻度。
  • \n
  • 删除完整块之间的中断。
  • \n
  • 添加颜色支持。
  • \n
\n


J. *_*ron 9

def printProgressBar(value,label):\n    n_bar = 40 #size of progress bar\n    max = 100\n    j= value/max\n    sys.stdout.write('\\r')\n    bar = '\xe2\x96\x88' * int(n_bar * j)\n    bar = bar + '-' * int(n_bar * (1-j))\n\n    sys.stdout.write(f"{label.ljust(10)} | [{bar:{n_bar}s}] {int(100 * j)}% ")\n    sys.stdout.flush()\n
Run Code Online (Sandbox Code Playgroud)\n
\n

称呼:

\n
\n
printProgressBar(30,"IP")\n
Run Code Online (Sandbox Code Playgroud)\n

知识产权| [\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\ xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88---------------------------- -] 30%

\n


Set*_*eth 9

成为纯Python并且不进行系统调用:

from time import sleep

for i in range(21):
    spaces = " " * (20 - i)
    percentage = 5*i
    print(f"\r[{'='*i}{spaces}]{percentage}%", flush=True, end="")
    sleep(0.25)
Run Code Online (Sandbox Code Playgroud)


STG*_*STG 6

进一步改进,使用函数作为:

import sys

def printProgressBar(i,max,postText):
    n_bar =10 #size of progress bar
    j= i/max
    sys.stdout.write('\r')
    sys.stdout.write(f"[{'=' * int(n_bar * j):{n_bar}s}] {int(100 * j)}%  {postText}")
    sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

调用示例:

total=33
for i in range(total):
    printProgressBar(i,total,"blah")
    sleep(0.05)  
Run Code Online (Sandbox Code Playgroud)

输出:

[================================================  ] 96%  blah  
Run Code Online (Sandbox Code Playgroud)


小智 5

基于上述答案和关于CLI进度条的其他类似问题,我想我得到了所有这些问题的一般共同答案.请访问/sf/answers/1110253021/查看

这是该函数的副本,但经过修改以适合您的风格:

import time, sys

# update_progress() : Displays or updates a console progress bar
## Accepts a float between 0 and 1. Any int will be converted to a float.
## A value under 0 represents a 'halt'.
## A value at 1 or bigger represents 100%
def update_progress(progress):
    barLength = 20 # Modify this to change the length of the progress bar
    status = ""
    if isinstance(progress, int):
        progress = float(progress)
    if not isinstance(progress, float):
        progress = 0
        status = "error: progress var must be float\r\n"
    if progress < 0:
        progress = 0
        status = "Halt...\r\n"
    if progress >= 1:
        progress = 1
        status = "Done...\r\n"
    block = int(round(barLength*progress))
    text = "\rPercent: [{0}] {1}% {2}".format( "="*block + " "*(barLength-block), progress*100, status)
    sys.stdout.write(text)
    sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

好像

百分比:[====================] 99.0%


now*_*wox 5

如果你正在开发一个命令行界面,我建议你看看click哪个非常好:

import click
import time

for filename in range(3):
    with click.progressbar(range(100), fill_char='=', empty_char=' ') as bar:
        for user in bar:
            time.sleep(0.01)
Run Code Online (Sandbox Code Playgroud)

这里你得到的输出:

$ python test.py
  [====================================]  100%
  [====================================]  100%
  [=========                           ]   27%
Run Code Online (Sandbox Code Playgroud)


Ste*_*ell 5

正如Mark Rushakoff 的解决方案中所述,您可以输出回车符 ,sys.stdout.write('\r')以将光标重置到行首。为了推广该解决方案,同时还实现Python 3 的 f-Strings,您可以使用

from time import sleep
import sys

n_bar = 50
iterable = range(33)  # for demo purposes
n_iter = len(iterable)
for i, item in enumerate(iterable):
    j = (i + 1) / n_iter

    sys.stdout.write('\r')
    sys.stdout.write(f"[{'=' * int(n_bar * j):{n_bar}s}] {int(100 * j)}%")
    sys.stdout.flush()

    sleep(0.05)  
    # do something with <item> here
Run Code Online (Sandbox Code Playgroud)