控制台中的文本进度条

bob*_*205 388 python console updating progress

有一个很好的方法来做到以下几点?

我写了一个简单的控制台应用程序,使用ftplib从FTP服务器上传和下载文件.

每次下载一些数据块时,我都想更新文本进度条,即使它只是一个数字.

但我不想删除所有打印到控制台的文本.(执行"清除"然后打印更新的百分比.)

Gre*_*ick 378

以下是我经常使用的许多答案的汇总.

# Print iterations progress
def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '?', printEnd = "\r"):
    """
    Call in a loop to create terminal progress bar
    @params:
        iteration   - Required  : current iteration (Int)
        total       - Required  : total iterations (Int)
        prefix      - Optional  : prefix string (Str)
        suffix      - Optional  : suffix string (Str)
        decimals    - Optional  : positive number of decimals in percent complete (Int)
        length      - Optional  : character length of bar (Int)
        fill        - Optional  : bar fill character (Str)
        printEnd    - Optional  : end character (e.g. "\r", "\r\n") (Str)
    """
    percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
    filledLength = int(length * iteration // total)
    bar = fill * filledLength + '-' * (length - filledLength)
    print('\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix), end = printEnd)
    # Print New Line on Complete
    if iteration == total: 
        print()
Run Code Online (Sandbox Code Playgroud)

样品用法:

import time

# A List of Items
items = list(range(0, 57))
l = len(items)

# Initial call to print 0% progress
printProgressBar(0, l, prefix = 'Progress:', suffix = 'Complete', length = 50)
for i, item in enumerate(items):
    # Do stuff...
    time.sleep(0.1)
    # Update Progress Bar
    printProgressBar(i + 1, l, prefix = 'Progress:', suffix = 'Complete', length = 50)
Run Code Online (Sandbox Code Playgroud)

样本输出:

Progress: |?????????????????????????????????????????????-----| 90.0% Complete
Run Code Online (Sandbox Code Playgroud)

  • 这个片段效果很棒!我确实遇到了一些小问题,所以我做了一些小编辑(PEP-8,非ascii字符的默认编码)并在这里把它们放在一个要点:https://gist.github.com/aubricus/f91fb55dc6ba5557fbab06119420dd6a (19认同)
  • 要使其在某些 IDE 中工作(例如 Windows 上的 PyCharm),您可能需要将 `end = '\r'` 更改为 `end = ''`。 (6认同)
  • 值得注意的是,除非您使用Python 2 @Aubricus,否则不需要UTF-8声明 (2认同)
  • @MattClimbs这是为Python 3编写的,默认情况下使用UTF-8编码.您可以更改函数的默认填充参数(UTF-8字符),也可以使用UTF-8声明.请参阅上面评论中的要点,了解UTF-8声明的外观示例. (2认同)

Ste*_*hen 298

写'\ r'会将光标移回到行的开头.

这显示一个百分比计数器:

import time
import sys

for i in range(100):
    time.sleep(1)
    sys.stdout.write("\r%d%%" % i)
    sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

  • @moose它代表"关闭一个bug" (8认同)
  • 这个例子也产生了一个OBOB,它以99%的速度加载 (7认同)
  • 粘贴然后跑了.它每次都打印到一个新行.我希望在同一行更新号码.:) (3认同)
  • @ bobber205:编辑,试试`sys.stdout.write` (2认同)
  • @Nick `\r` 适用于所有平台。 (2认同)
  • `print`有一个`end`参数:http://stackoverflow.com/a/8436827/1959808 (2认同)
  • 要添加@IoannisFilippidis所说的内容,`print`也有一个`flush`参数:https://docs.python.org/3/library/functions.html#print (2认同)

jfs*_*jfs 165

tqdm:在一秒钟内为你的循环添加一个进度表:

>>> import time
>>> from tqdm import tqdm
>>> for i in tqdm(range(100)):
...     time.sleep(1)
... 
|###-------| 35/100  35% [elapsed: 00:35 left: 01:05,  1.00 iters/sec]
Run Code Online (Sandbox Code Playgroud)

tqdm repl session

  • @xotonic 链接说它是 [ptpython](https://github.com/jonathanslenders/ptpython) (2认同)

avi*_*ldg 109

写一个\r到控制台.这是一个"回车",它会导致它后面的所有文本在行的开头回显.就像是:

def update_progress(progress):
    print '\r[{0}] {1}%'.format('#'*(progress/10), progress)
Run Code Online (Sandbox Code Playgroud)

这将给你类似的东西: [ ########## ] 100%

  • 做`\ r`然后再写出整行.基本上:`print("\ rProgress:[{0:50s}] {1:.1f}%".format('#'*int(amtDone*50),amtDone*100))`,其中`amtDone`是一个介于0和1之间的浮点数. (19认同)
  • 在'print`的末尾附加一个逗号`,`为我工作. (14认同)
  • 最好使用`sys.stdout.write`而不是`print`.随着`print`我得到了换行符. (13认同)
  • 在python3中使用print(....,end =''),你将不会有任何换行符 (9认同)
  • 总结Python3前贡献:`print("\ rProgress:[{0:50s}] {1:.1f}%".format('#'*int(workdone*50),workdone*100),end =" ",flush = True)`,其中`workdone`是介于0和1之间的浮点数,例如,`workdone = parsed_dirs/total_dirs` (6认同)

Vla*_*yev 67

它不到10行代码.

这里的要点:https://gist.github.com/vladignatyev/06860ec2040cb497f0f3

import sys


def progress(count, total, suffix=''):
    bar_len = 60
    filled_len = int(round(bar_len * count / float(total)))

    percents = round(100.0 * count / float(total), 1)
    bar = '=' * filled_len + '-' * (bar_len - filled_len)

    sys.stdout.write('[%s] %s%s ...%s\r' % (bar, percents, '%', suffix))
    sys.stdout.flush()  # As suggested by Rom Ruben
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 将"sys.stdout.flush()"添加到函数末尾. (2认同)

The*_*Cat 58

试试由Mozart of Python,Armin Ronacher编写的点击库.

$ pip install click # both 2 and 3 compatible
Run Code Online (Sandbox Code Playgroud)

要创建一个简单的进度条:

import click

with click.progressbar(range(1000000)) as bar:
    for i in bar:
        pass 
Run Code Online (Sandbox Code Playgroud)

这就是它的样子:

# [###-------------------------------]    9%  00:01:14
Run Code Online (Sandbox Code Playgroud)

根据您的心灵内容定制:

import click, sys

with click.progressbar(range(100000), file=sys.stderr, show_pos=True, width=70, bar_template='(_(_)=%(bar)sD(_(_| %(info)s', fill_char='=', empty_char=' ') as bar:
    for i in bar:
        pass
Run Code Online (Sandbox Code Playgroud)

自定义外观:

(_(_)===================================D(_(_| 100000/100000 00:00:02
Run Code Online (Sandbox Code Playgroud)

还有更多选项,请参阅API文档:

 click.progressbar(iterable=None, length=None, label=None, show_eta=True, show_percent=None, show_pos=False, item_show_func=None, fill_char='#', empty_char='-', bar_template='%(label)s [%(bar)s] %(info)s', info_sep=' ', width=36, file=None, color=None)
Run Code Online (Sandbox Code Playgroud)


Joe*_*nux 32

我意识到我已经迟到了,但是这里有一个我写的略带百胜风格(Red Hat)(这里不是100%准确,但如果你使用进度条达到那个准确度,那么你无论如何都是错的:

import sys

def cli_progress_test(end_val, bar_length=20):
    for i in xrange(0, end_val):
        percent = float(i) / end_val
        hashes = '#' * int(round(percent * bar_length))
        spaces = ' ' * (bar_length - len(hashes))
        sys.stdout.write("\rPercent: [{0}] {1}%".format(hashes + spaces, int(round(percent * 100))))
        sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

应该产生这样的东西:

Percent: [##############      ] 69%
Run Code Online (Sandbox Code Playgroud)

......托架保持静止,只有哈希增加.

这可能更适合作为装饰者.再过一天......


scr*_*pts 17

检查这个库:clint

它有很多功能,包括进度条:

from time import sleep  
from random import random  
from clint.textui import progress  
if __name__ == '__main__':
    for i in progress.bar(range(100)):
        sleep(random() * 0.2)

    for i in progress.dots(range(100)):
        sleep(random() * 0.2)
Run Code Online (Sandbox Code Playgroud)

链接提供其功能的快速概述


Wol*_*lph 12

这是一个用Python编写的进度条的一个很好的例子:http://nadiana.com/animated-terminal-progress-bar-in-python

但如果你想自己写.您可以使用该curses模块使事情变得更容易:)

[编辑]也许更容易的不是诅咒这个词.但如果你想创造一个完整的cui而不是curses为你照顾很多东西.

[编辑]由于旧的链接已经死了,我已经提出了我自己的Python Progressbar版本,请点击此处:https://github.com/WoLpH/python-progressbar

  • `curses`?更轻松?嗯.... (14认同)
  • 死链接,这是不在你的答案中发布链接内容的价格-__- (2认同)

ash*_*2py 11

import time,sys

for i in range(100+1):
    time.sleep(0.1)
    sys.stdout.write(('='*i)+(''*(100-i))+("\r [ %d"%i+"% ] "))
    sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

产量

[29%] ===================


Fra*_*fin 7

并且,只是为了添加到堆中,这是您可以使用的对象

import sys

class ProgressBar(object):
    DEFAULT_BAR_LENGTH = 65
    DEFAULT_CHAR_ON  = '='
    DEFAULT_CHAR_OFF = ' '

    def __init__(self, end, start=0):
        self.end    = end
        self.start  = start
        self._barLength = self.__class__.DEFAULT_BAR_LENGTH

        self.setLevel(self.start)
        self._plotted = False

    def setLevel(self, level):
        self._level = level
        if level < self.start:  self._level = self.start
        if level > self.end:    self._level = self.end

        self._ratio = float(self._level - self.start) / float(self.end - self.start)
        self._levelChars = int(self._ratio * self._barLength)

    def plotProgress(self):
        sys.stdout.write("\r  %3i%% [%s%s]" %(
            int(self._ratio * 100.0),
            self.__class__.DEFAULT_CHAR_ON  * int(self._levelChars),
            self.__class__.DEFAULT_CHAR_OFF * int(self._barLength - self._levelChars),
        ))
        sys.stdout.flush()
        self._plotted = True

    def setAndPlot(self, level):
        oldChars = self._levelChars
        self.setLevel(level)
        if (not self._plotted) or (oldChars != self._levelChars):
            self.plotProgress()

    def __add__(self, other):
        assert type(other) in [float, int], "can only add a number"
        self.setAndPlot(self._level + other)
        return self
    def __sub__(self, other):
        return self.__add__(-other)
    def __iadd__(self, other):
        return self.__add__(other)
    def __isub__(self, other):
        return self.__add__(-other)

    def __del__(self):
        sys.stdout.write("\n")

if __name__ == "__main__":
    import time
    count = 150
    print "starting things:"

    pb = ProgressBar(count)

    #pb.plotProgress()
    for i in range(0, count):
        pb += 1
        #pb.setAndPlot(i + 1)
        time.sleep(0.01)
    del pb

    print "done"
Run Code Online (Sandbox Code Playgroud)

结果是:

starting things:
  100% [=================================================================]
done
Run Code Online (Sandbox Code Playgroud)

这通常被认为是"超过顶部",但是当你经常使用它时它很方便


Pau*_*McG 6

在Python命令行(不在任何IDE或开发环境中)运行此命令:

>>> import threading
>>> for i in range(50+1):
...   threading._sleep(0.5)
...   print "\r%3d" % i, ('='*i)+('-'*(50-i)),
Run Code Online (Sandbox Code Playgroud)

在我的Windows系统上正常工作.


小智 6

安装tqdm.(pip install tqdm)并按如下方式使用它:

import time
from tqdm import tqdm
for i in tqdm(range(1000)):
    time.sleep(0.01)
Run Code Online (Sandbox Code Playgroud)

这是一个10秒的进度条,它会输出这样的东西:

47%|???????????????????                     | 470/1000 [00:04<00:05, 98.61it/s]
Run Code Online (Sandbox Code Playgroud)


小智 6

尝试安装这个包 pip install progressbar2::

import time
import progressbar

for i in progressbar.progressbar(range(100)):
    time.sleep(0.02)
Run Code Online (Sandbox Code Playgroud)

进度条 github:https : //github.com/WoLpH/python-progressbar


小智 5

一个非常简单的解决方案是将以下代码放入循环中:

将其放入文件的正文(即顶部)中:

import sys
Run Code Online (Sandbox Code Playgroud)

将其放入循环体中:

sys.stdout.write("-") # prints a dash for each iteration of loop
sys.stdout.flush() # ensures bar is displayed incrementally
Run Code Online (Sandbox Code Playgroud)