11

给Python代码加上酷炫进度条的几种姿势

 4 years ago
source link: https://blog.csdn.net/dQCFKyQDXYm3F8rB0/article/details/106535960
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

ZzeyeeU.jpg!web

RreYzqm.jpg!web

作者 | 刘早起

来源 | 早起Python(ID: zaoqi-python)

大家好,在下载某些文件的时候你一定会不时盯着进度条,在写代码的时候使用进度条可以便捷的观察任务处理情况,除了使用print来打印之外,今天本文就介绍几种给你的Python代码加上酷炫的进度条的方式。

jQRNbiy.jpg!web

vmYnU3e.jpg!web

自定义ProgressBar

最原始的办法就是不借助任何第三方工具,自己写一个进度条函数,使用time模块配合sys模块即可

import sys
import time

def progressbar(it, prefix="", size=60, file=sys.stdout):
    count = len(it)
    def show(j):
        x = int(size*j/count)
        file.write("%s[%s%s] %i/%i\r" % (prefix, "#"*x, "."*(size-x), j, count))
        file.flush()        
    show(0)
    for i, item in enumerate(it):
        yield item
        show(i+1)
    file.write("\n")
    file.flush()

    
for i in progressbar(range(15), "Computing: ", 40):
    do_something()
    time.sleep(0.1)

2M3A7fF.jpg!web

自己定义的好处就是可以将进度条定义成我们想要的形式比如上面就是使用 # · 来输出,为什么不用 print ?因为 sys.stdout 就是print的一种默认输出格式, sys.stdout.write() 可以不换行打印, sys.stdout.flush() 可以立即刷新输出的内容。当然也可以封装成类来更好的使用 [1]  ,但效果是类似的。

from __future__ import print_function
import sys
import re


class ProgressBar(object):
    DEFAULT = 'Progress: %(bar)s %(percent)3d%%'
    FULL = '%(bar)s %(current)d/%(total)d (%(percent)3d%%) %(remaining)d to go'

    def __init__(self, total, width=40, fmt=DEFAULT, symbol='=',
                 output=sys.stderr):
        assert len(symbol) == 1

        self.total = total
        self.width = width
        self.symbol = symbol
        self.output = output
        self.fmt = re.sub(r'(?P<name>%\(.+?\))d',
            r'\g<name>%dd' % len(str(total)), fmt)

        self.current = 0

    def __call__(self):
        percent = self.current / float(self.total)
        size = int(self.width * percent)
        remaining = self.total - self.current
        bar = '[' + self.symbol * size + ' ' * (self.width - size) + ']'

        args = {
            'total': self.total,
            'bar': bar,
            'current': self.current,
            'percent': percent * 100,
            'remaining': remaining
        }
        print('\r' + self.fmt % args, file=self.output, end='')

    def done(self):
        self.current = self.total
        self()
        print('', file=self.output)
        
from time import sleep

progress = ProgressBar(80, fmt=ProgressBar.FULL)

for x in range(progress.total):
    progress.current += 1
    progress()
    sleep(0.1)
progress.done()

JRV3iyv.jpg!web

euUjAvZ.jpg!web

tqdm

之前我们说了,自定义的好处就是可以自己修改,那么使用第三方库的好处就是可以偷懒,不用自己写,拿来就能用。比如提到Python进度条那肯定会想到常用的tqdm,安装很简单 pip install tqdm 即可,使用也很简单,几行代码即可实现上面的进度条

from tqdm import trange
import time
for i in trange(10): 
    time.sleep(1)

f2q2Ibe.jpg!web

当然tqdm作为老牌的Python进度条工具, 循环处理、多进程、多线程、递归处理等都是支持的,你可以在官方GitHub上学习 [2]  、解锁更多的玩法。

NNfMrqz.jpg!web

Rich

上面两种实现Python进度条的方法都学会了吗,虽然简单但是看上去并不漂亮,颜色也比较单调。所以最后压轴出场的就是一款比较小众的第三方库 Rich [3]  。Rich主要是用于在终端中打印丰富多彩的文本(最高支持1670万色)

mAJzeq2.jpg!web

所以当然可以使用Rich打印进度条,显示完成百分比,剩余时间,数据传输速度等都可以。并且样式更加酷炫,并且它是高度可配置的,因此我们可以对其进行自定义以显示所需的任何信息。使用也很简单,比如我们使用Rich来实现一个最简单的进度条。

from rich.progress import track
import  time

for step in track(range(30)):
    print('早起Python')
    time.sleep(0.5)

aIjamuj.jpg!web

同时Rich支持多个进度条,这在多任务情况下监控的进度很有用(使用方法见官方文档)

Bfmi2eV.jpg!web

参考资料

[1] stackoverflow: https://stackoverflow.com/questions/3160699/python-progress-bar
[2]
Tqdm: https://github.com/tqdm/tqdm
[3]
Rich: https://github.com/willmcgugan/rich

推荐阅读
你点的每个“在看”,我都认真当成了喜欢

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK