【问题标题】:Text progress bar in terminal with block characters [closed]终端中带有块字符的文本进度条[关闭]
【发布时间】:2011-03-11 12:59:00
【问题描述】:

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

我希望该应用程序为用户显示其下载/上传进度的一些可视化;每次下载数据块时,我希望它提供进度更新,即使它只是像百分比这样的数字表示。

重要的是,我想避免擦除前几行打印到控制台的所有文本(即,我不想在打印更新的进度时“清除”整个终端)。

这似乎是一项相当普遍的任务——我如何才能制作一个进度条或类似的可视化效果来输出到我的控制台,同时保留之前的程序输出?

【问题讨论】:

  • 嗯,看起来像昨天问的这个问题的重复:stackoverflow.com/questions/3160699/python-progress-bar/3162864所以,你应该使用鱼pypi.python.org/pypi/fish
  • “只使用 GUI”误解了 GUI 在某些情况下(快速学习曲线、临时探索性或交互式或一次性活动)非常有用,而命令行工具在其他情况下非常有用(专家用户,即时编写临时应用程序以多次执行精心定义的操作。)
  • 我投票决定重新开放。这个问题并没有让我觉得太宽泛。
  • 我认为您正在寻找的是 tqdm... 虽然我也不知道为什么 SO 会提示我重新审核旧问题的重新投票。
  • 如果您不想要外部软件包,我想这里是best answer

标签: python console progress updating


【解决方案1】:

Python 3

一个简单、可自定义的进度条

以下是我经常使用的许多答案的汇总(无需导入)。

注意:此答案中的所有代码都是为 Python 3 创建的;请参阅答案的结尾以将此代码与 Python 2 一起使用。

# 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(f'\r{prefix} |{bar}| {percent}% {suffix}', end = printEnd)
    # Print New Line on Complete
    if iteration == total: 
        print()

示例用法

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)

样本输出

Progress: |█████████████████████████████████████████████-----| 90.0% Complete

更新

在 cmets 中讨论了一个允许进度条动态调整到终端窗口宽度的选项。虽然我不推荐这样做,但这里有一个实现此功能的gist(并注意注意事项)。

上述的单一调用版本

下面的评论引用了一个很好的answer 回复类似问题。我喜欢它展示的易用性并写了一个类似的,但选择省略 sys 模块的导入,同时添加上面原始 printProgressBar 函数的一些功能。

与上述原始函数相比,这种方法的一些好处包括消除了对函数的初始调用以在 0% 处打印进度条以及使用 enumerate 成为可选(即不再明确要求函数工作)。

def progressBar(iterable, prefix = '', suffix = '', decimals = 1, length = 100, fill = '█', printEnd = "\r"):
    """
    Call in a loop to create terminal progress bar
    @params:
        iterable    - Required  : iterable object (Iterable)
        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)
    """
    total = len(iterable)
    # Progress Bar Printing Function
    def printProgressBar (iteration):
        percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
        filledLength = int(length * iteration // total)
        bar = fill * filledLength + '-' * (length - filledLength)
        print(f'\r{prefix} |{bar}| {percent}% {suffix}', end = printEnd)
    # Initial Call
    printProgressBar(0)
    # Update Progress Bar
    for i, item in enumerate(iterable):
        yield item
        printProgressBar(i + 1)
    # Print New Line on Complete
    print()

示例用法

import time

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

# A Nicer, Single-Call Usage
for item in progressBar(items, prefix = 'Progress:', suffix = 'Complete', length = 50):
    # Do stuff...
    time.sleep(0.1)

样本输出

Progress: |█████████████████████████████████████████████-----| 90.0% Complete

Python 2

要在 Python 2 中使用上述函数,请在脚本顶部将编码设置为 UTF-8:

# -*- coding: utf-8 -*-

并替换这一行中的 Python 3 字符串格式:

print(f'\r{prefix} |{bar}| {percent}% {suffix}', end = printEnd)

使用 Python 2 字符串格式化:

print('\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix), end = printEnd)

【讨论】:

  • 这个 sn-p 效果很好!我确实遇到了一些小问题,所以我做了一些小修改(PEP-8,非 ascii 字符的默认编码),并将它们放在一个要点中:gist.github.com/aubricus/f91fb55dc6ba5557fbab06119420dd6a
  • 值得注意的是,除非您使用 Python 2 @Aubricus,否则不需要 UTF-8 声明
  • @MattClimbs 这是为默认使用 UTF-8 编码的 Python 3 编写的。您可以更改函数的默认填充参数(UTF-8 字符),也可以使用 UTF-8 声明。有关 UTF-8 声明的示例,请参阅上面评论中的要点。
  • 谢谢,很好的总结,终端大小的检测也可能对这个函数有用# Size of terminal rows, columns = [int(x) for x in os.popen('stty size', 'r').read().split()] columns 应该传递给长度来调整进度条大小到终端窗口。虽然应该减少条的进度部分的长度(通过此字符串中的前缀、后缀、百分比和附加字符的长度'\r%s |%s| %s%% %s'
  • 要让它在某些 IDE 中工作(例如 Windows 上的 PyCharm),您可能需要将 end = '\r' 更改为 end = ''
【解决方案2】:

写入 '\r' 会将光标移回行首。

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

import time
import sys

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

【讨论】:

【解决方案3】:

tqdm: add a progress meter to your loops in a second:

>>> 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]

【讨论】:

  • 你用的是什么python shell?
  • @xotonic 链接说它是ptpython
  • 当然,为 20 行函数拉一个库:D
  • @iperov:像往常一样,需要权衡取舍。除非您可以列出不这样做的具体原因,否则请使用其他人必须维护的代码。我都记得:推出我自己的代码(仅几行显示进度)和在各种情况下使用 tqdm(有 1k+ 次提交是有原因的)。
  • @jfs 当然。但是我经常发现库开发者犯了错误,我依赖他们的项目崩溃了。这就是为什么我更喜欢制作自己的函数实现,这些实现具有更可预测的行为。
【解决方案4】:

\r 写入控制台。那是一个"carriage return",它会导致它后面的所有文本都在行首回显。比如:

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

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

【讨论】:

  • \r 然后再写出整行。基本上:print("\rProgress: [{0:50s}] {1:.1f}%".format('#' * int(amtDone * 50), amtDone * 100)),其中amtDone 是一个介于 0 和 1 之间的浮点数。
  • 使用sys.stdout.write 比使用print 更好。有了print,我得到了换行符。
  • print 的末尾添加一个逗号, 对我有用。
  • 在 python3 中使用 print(...., end='') 并且你不会有任何换行符
  • 总结 Python3 以前的贡献:print("\rProgress: [{0:50s}] {1:.1f}%".format('#' * int(workdone * 50), workdone*100), end="", flush=True),其中workdone 是介于 0 和 1 之间的浮点数,例如,workdone = parsed_dirs/total_dirs
【解决方案5】:

不到 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

【讨论】:

  • 在函数末尾添加“sys.stdout.flush()”。
  • 对我来说是换行了
  • @GM 你使用什么操作系统/平台?
  • 我不知道为什么如果我从 spyder ide 运行它不起作用,但如果我从 ipython 控制台运行它就可以了!
【解决方案6】:

试试 Python 的莫扎特 Armin Ronacher 编写的 click 库。

$ pip install click # both 2 and 3 compatible

创建一个简单的进度条:

import click

with click.progressbar(range(1000000)) as bar:
    for i in bar:
        pass 

这就是它的样子:

# [###-------------------------------]    9%  00:01:14

根据你的内心定制:

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

自定义外观:

(_(_)===================================D(_(_| 100000/100000 00:00:02

还有更多选项,请参阅API docs

 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)

【讨论】:

  • 不错!从我一直使用的库中添加了一行代码。
【解决方案7】:

我意识到我玩游戏迟到了,但这是我写的一个略带 Yum 风格的(红帽)(这里不是 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()

应该产生如下所示的东西:

Percent: [##############      ] 69%

...括号保持静止,只有哈希值增加。

这可能更适合作为装饰器。改天……

【讨论】:

    【解决方案8】:

    检查这个库: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)
    

    link 提供了对其功能的快速概述

    【讨论】:

      【解决方案9】:

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

      但是如果你想自己写的话。你可以使用curses 模块让事情变得更简单:)

      [编辑] 也许更容易不是诅咒这个词。但是如果你想创建一个成熟的 cui,curses 会为你处理很多事情。

      [编辑] 由于旧链接已失效,我已经建立了自己版本的 Python 进度条,请在此处获取:https://github.com/WoLpH/python-progressbar

      【讨论】:

      • curses?更轻松?嗯....
      • 一篇很棒的文章,我打算给它一个链接,但在我的书签中找不到:)
      • @Aviral Dasgupta:很公平,更容易在这里可能不是正确的词。虽然它可以为您节省大量工作,但这实际上取决于您要查找的内容。
      • 不寻找与此相关的任何东西,但无论如何谢谢。 :)
      • 死链接,这是在您的答案中不发布链接内容的代价-__-
      【解决方案10】:
      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()
      

      输出

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

      【讨论】:

        【解决方案11】:

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

        import time
        from tqdm import tqdm
        for i in tqdm(range(1000)):
            time.sleep(0.01)
        

        这是一个 10 秒的进度条,会输出如下内容:

        47%|██████████████████▊                     | 470/1000 [00:04<00:05, 98.61it/s]
        

        【讨论】:

          【解决方案12】:

          而且,只是为了添加到堆中,这里有一个你可以使用的对象

          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"
          

          结果:

          starting things:
            100% [=================================================================]
          done
          

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

          【讨论】:

          • 谢谢。小修复,plotProgress 方法应该使用行 sys.stdout.flush() 否则在任务完成之前可能不会绘制进度条(就像在 mac 终端中发生的那样)。
          • 我喜欢这个!!!相当容易使用!!!谢谢你
          【解决方案13】:

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

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

          在我的 Windows 系统上运行良好。

          【讨论】:

            【解决方案14】:

            尝试安装这个包:pip install progressbar2

            import time
            import progressbar
            
            for i in progressbar.progressbar(range(100)):
                time.sleep(0.02)
            

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

            【讨论】:

            • 该存储库的所有者已经回答得更早了。
            【解决方案15】:
            【解决方案16】:

            我正在使用progress from reddit。我喜欢它,因为它可以在一行中打印每个项目的进度,并且它不应该从程序中删除打印输出。

            编辑:固定链接

            【讨论】:

            • 您的链接已损坏 - 源代码中的实际行是第 1274 行,而不是第 1124 行!所以,正确的链接是这个:github.com/reddit/reddit/blob/master/r2/r2/lib/utils/…
            • 这个变体在我看来是最好的设计:它使用迭代器并且可能适用于任何类型的可测量工作,它显示经过的时间。
            【解决方案17】:

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

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

            import sys
            

            把它放在你的循环体中:

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

            【讨论】:

              【解决方案18】:

              基于上述答案和其他关于 CLI 进度条的类似问题,我想我对所有这些问题都有一个普遍的共同答案。在https://stackoverflow.com/a/15860757/2254146查看它

              总之,代码是这样的:

              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 = 10 # 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()
              

              看起来像

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

              【讨论】:

                【解决方案19】:

                我推荐使用 tqdm - https://pypi.python.org/pypi/tqdm - 这使得将任何可迭代或进程转换为进度条变得简单,并处理所有需要终端的混乱。

                来自文档:“tqdm 可以轻松支持回调/挂钩和手动更新。这是 urllib 的示例”

                import urllib
                from tqdm import tqdm
                
                def my_hook(t):
                  """
                  Wraps tqdm instance. Don't forget to close() or __exit__()
                  the tqdm instance once you're done with it (easiest using `with` syntax).
                
                  Example
                  -------
                
                  >>> with tqdm(...) as t:
                  ...     reporthook = my_hook(t)
                  ...     urllib.urlretrieve(..., reporthook=reporthook)
                
                  """
                  last_b = [0]
                
                  def inner(b=1, bsize=1, tsize=None):
                    """
                    b  : int, optional
                        Number of blocks just transferred [default: 1].
                    bsize  : int, optional
                        Size of each block (in tqdm units) [default: 1].
                    tsize  : int, optional
                        Total size (in tqdm units). If [default: None] remains unchanged.
                    """
                    if tsize is not None:
                        t.total = tsize
                    t.update((b - last_b[0]) * bsize)
                    last_b[0] = b
                  return inner
                
                eg_link = 'http://www.doc.ic.ac.uk/~cod11/matryoshka.zip'
                with tqdm(unit='B', unit_scale=True, miniters=1,
                          desc=eg_link.split('/')[-1]) as t:  # all optional kwargs
                    urllib.urlretrieve(eg_link, filename='/dev/null',
                                       reporthook=my_hook(t), data=None)
                

                【讨论】:

                  【解决方案20】:
                  import sys
                  def progresssbar():
                           for i in range(100):
                              time.sleep(1)
                              sys.stdout.write("%i\r" % i)
                  
                  progressbar()
                  

                  注意:如果您在交互式解释器中运行此程序,则会打印出额外的数字

                  【讨论】:

                    【解决方案21】:

                    哈哈,我刚刚为此写了一个完整的东西 这里的代码记住你不能在做块 ascii 时使用 unicode 我使用 cp437

                    import os
                    import time
                    def load(left_side, right_side, length, time):
                        x = 0
                        y = ""
                        print "\r"
                        while x < length:
                            space = length - len(y)
                            space = " " * space
                            z = left + y + space + right
                            print "\r", z,
                            y += "█"
                            time.sleep(time)
                            x += 1
                        cls()
                    

                    你这样称呼它

                    print "loading something awesome"
                    load("|", "|", 10, .01)
                    

                    看起来像这样

                    loading something awesome
                    |█████     |
                    

                    【讨论】:

                      【解决方案22】:

                      根据上面的建议,我计算出了进度条。

                      但是我想指出一些缺点

                      1. 每次刷新进度条都会换行

                        print('\r[{0}]{1}%'.format('#' * progress* 10, progress))  
                        

                        像这样:
                        [] 0%
                        [#]10%
                        [##]20%
                        [###]30%

                      2.方括号“]”和右侧的百分比数字随着“###”变长而右移。
                      3. 如果表达式'progress / 10'不能返回一个整数,将会出错。

                      以下代码将解决上述问题。

                      def update_progress(progress, total):  
                          print('\r[{0:10}]{1:>2}%'.format('#' * int(progress * 10 /total), progress), end='')
                      

                      【讨论】:

                        【解决方案23】:

                        python终端进度条代码

                        import sys
                        import time
                        
                        max_length = 5
                        at_length = max_length
                        empty = "-"
                        used = "%"
                        
                        bar = empty * max_length
                        
                        for i in range(0, max_length):
                            at_length -= 1
                        
                            #setting empty and full spots
                            bar = used * i
                            bar = bar+empty * at_length
                        
                            #\r is carriage return(sets cursor position in terminal to start of line)
                            #\0 character escape
                        
                            sys.stdout.write("[{}]\0\r".format(bar))
                            sys.stdout.flush()
                        
                            #do your stuff here instead of time.sleep
                            time.sleep(1)
                        
                        sys.stdout.write("\n")
                        sys.stdout.flush()
                        

                        【讨论】:

                          【解决方案24】:

                          python 模块 progressbar 是一个不错的选择。 这是我的典型代码:

                          import time
                          import progressbar
                          
                          widgets = [
                              ' ', progressbar.Percentage(),
                              ' ', progressbar.SimpleProgress(format='(%(value_s)s of %(max_value_s)s)'),
                              ' ', progressbar.Bar('>', fill='.'),
                              ' ', progressbar.ETA(format_finished='- %(seconds)s  -', format='ETA: %(seconds)s', ),
                              ' - ', progressbar.DynamicMessage('loss'),
                              ' - ', progressbar.DynamicMessage('error'),
                              '                          '
                          ]
                          
                          bar = progressbar.ProgressBar(redirect_stdout=True, widgets=widgets)
                          bar.start(100)
                          for i in range(100):
                              time.sleep(0.1)
                              bar.update(i + 1, loss=i / 100., error=i)
                          bar.finish()
                          

                          【讨论】:

                            【解决方案25】:

                            我写了一个简单的进度条:

                            def bar(total, current, length=10, prefix="", filler="#", space=" ", oncomp="", border="[]", suffix=""):
                                if len(border) != 2:
                                    print("parameter 'border' must include exactly 2 symbols!")
                                    return None
                            
                                print(prefix + border[0] + (filler * int(current / total * length) +
                                                                  (space * (length - int(current / total * length)))) + border[1], suffix, "\r", end="")
                                if total == current:
                                    if oncomp:
                                        print(prefix + border[0] + space * int(((length - len(oncomp)) / 2)) +
                                              oncomp + space * int(((length - len(oncomp)) / 2)) + border[1], suffix)
                                    if not oncomp:
                                        print(prefix + border[0] + (filler * int(current / total * length) +
                                                                    (space * (length - int(current / total * length)))) + border[1], suffix)
                            

                            如你所见,它有:条的长度、前缀和后缀、填充符、空格、100%(oncomp) 上的条中的文本和边框

                            这里是一个例子:

                            from time import sleep, time
                            start_time = time()
                            for i in range(10):
                                pref = str((i+1) * 10) + "% "
                                complete_text = "done in %s sec" % str(round(time() - start_time))
                                sleep(1)
                                bar(10, i + 1, length=20, prefix=pref, oncomp=complete_text)
                            

                            正在进行中:

                            30% [######              ]
                            

                            完成:

                            100% [   done in 9 sec   ] 
                            

                            【讨论】:

                              【解决方案26】:

                              汇总我在这里找到的一些想法,并加上估计的剩余时间:

                              import datetime, sys
                              
                              start = datetime.datetime.now()
                              
                              def print_progress_bar (iteration, total):
                              
                                  process_duration_samples = []
                                  average_samples = 5
                              
                                  end = datetime.datetime.now()
                              
                                  process_duration = end - start
                              
                                  if len(process_duration_samples) == 0:
                                      process_duration_samples = [process_duration] * average_samples
                              
                                  process_duration_samples = process_duration_samples[1:average_samples-1] + [process_duration]
                                  average_process_duration = sum(process_duration_samples, datetime.timedelta()) / len(process_duration_samples)
                                  remaining_steps = total - iteration
                                  remaining_time_estimation = remaining_steps * average_process_duration
                              
                                  bars_string = int(float(iteration) / float(total) * 20.)
                                  sys.stdout.write(
                                      "\r[%-20s] %d%% (%s/%s) Estimated time left: %s" % (
                                          '='*bars_string, float(iteration) / float(total) * 100,
                                          iteration,
                                          total,
                                          remaining_time_estimation
                                      ) 
                                  )
                                  sys.stdout.flush()
                                  if iteration + 1 == total:
                                      print 
                              
                              
                              # Sample usage
                              
                              for i in range(0,300):
                                  print_progress_bar(i, 300)
                              

                              【讨论】:

                                【解决方案27】:

                                对于python 3:

                                def progress_bar(current_value, total):
                                    increments = 50
                                    percentual = ((current_value/ total) * 100)
                                    i = int(percentual // (100 / increments ))
                                    text = "\r[{0: <{1}}] {2}%".format('=' * i, increments, percentual)
                                    print(text, end="\n" if percentual == 100 else "")
                                

                                【讨论】:

                                  【解决方案28】:

                                  这里是有效的代码,我在发布之前对其进行了测试:

                                  import sys
                                  def prg(prog, fillchar, emptchar):
                                      fillt = 0
                                      emptt = 20
                                      if prog < 100 and prog > 0:
                                          prog2 = prog/5
                                          fillt = fillt + prog2
                                          emptt = emptt - prog2
                                          sys.stdout.write("\r[" + str(fillchar)*fillt + str(emptchar)*emptt + "]" + str(prog) + "%")
                                          sys.stdout.flush()
                                      elif prog >= 100:
                                          prog = 100
                                          prog2 = prog/5
                                          fillt = fillt + prog2
                                          emptt = emptt - prog2
                                          sys.stdout.write("\r[" + str(fillchar)*fillt + str(emptchar)*emptt + "]" + str(prog) + "%" + "\nDone!")
                                          sys.stdout.flush()
                                      elif prog < 0:
                                          prog = 0
                                          prog2 = prog/5
                                          fillt = fillt + prog2
                                          emptt = emptt - prog2
                                          sys.stdout.write("\r[" + str(fillchar)*fillt + str(emptchar)*emptt + "]" + str(prog) + "%" + "\nHalted!")
                                          sys.stdout.flush()
                                  

                                  优点:

                                  • 20 个字符栏(每 5 个字符对应 1 个字符(按数字计算))
                                  • 自定义填充字符
                                  • 自定义空字符
                                  • 暂停(任何低于 0 的数字)
                                  • 完成(100 和任何超过 100 的数字)
                                  • 进度计数(0-100(低于和高于用于特殊功能))
                                  • 栏旁边的百分比数字,它是单行

                                  缺点:

                                  • 仅支持整数(但可以修改为支持整数,将除法设为整数除法,因此只需将 prog2 = prog/5 更改为 prog2 = int(prog/5)

                                  【讨论】:

                                    【解决方案29】:

                                    这是我的 Python 3 解决方案:

                                    import time
                                    for i in range(100):
                                        time.sleep(1)
                                        s = "{}% Complete".format(i)
                                        print(s,end=len(s) * '\b')
                                    

                                    '\b' 是一个反斜杠,用于字符串中的每个字符。 这在 Windows cmd 窗口中不起作用。

                                    【讨论】:

                                      【解决方案30】:

                                      Greenstick 2.7 的功能:

                                      def printProgressBar (iteration, total, prefix = '', suffix = '',decimals = 1, length = 100, fill = '#'):
                                      
                                      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),
                                      sys.stdout.flush()
                                      # Print New Line on Complete                                                                                                                                                                                                              
                                      if iteration == total:
                                          print()
                                      

                                      【讨论】:

                                        猜你喜欢
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2018-11-26
                                        • 1970-01-01
                                        • 1970-01-01
                                        相关资源
                                        最近更新 更多