tqdm详解


前言:使用python写项目时,或是被学长建议使用tqdm,或是在示例中看到别人使用tqdm。我总是疑惑,为什么要用tqdm显示程序进度,print不就够用了吗?tqdm是什么?如何使用?实现原理?有哪些优势和应用场景?今天在这篇文中做一个记录。


相关链接

Github:https://github.com/tqdm/tqdm

Document:https://tqdm.github.io/

中文参考资料:python进度条库tqdm详解

简介

tqdm官方文档中介绍到,tqdm是阿拉伯语中“进步”的意思。在代码中使用tqdm方法可以在迭代中显示进度条。

一个比较简单的使用方法是给tqdm一个可迭代的数据,即tqdm(iterable)

from tqdm import tqdm
for i in tqdm(range(10000)):
    ...

同样也可以在pipes中使用,但这部分将不会在本文中介绍。

$ seq 9999999 | tqdm --bytes | wc -l
75.2MB [00:00, 217MB/s]
9999999
$ 7z a -bd -r backup.7z docs/ | grep Compressing | \
    tqdm --total $(find docs/ -type f | wc -l) --unit files >> backup.log
100%|███████████████████████████████▉| 8014/8014 [01:37<00:00, 82.29files/s]

tqdm采用的是 MIT 许可证,具体内容参见维基百科:MIT许可证

参数说明

tqdm.tqdm是最常用的tqdm对象,用文档原文是说:

Decorate an iterable object, returning an iterator which acts exactly like the original iterable, but prints a dynamically updating progressbar every time a value is requested.

大意是,接受一个可迭代的对象,返回一个和原始可迭代对象完全一致的迭代器,但在每次请求值时,动态打印进度条。

除去该方法中的@staticmethod@classmethod,介绍tqdm中主要的实例方法。

__init__

def __init__(iterable=None, desc=None, total=None, leave=True, file=None, ncols=None, mininterval=0.1, maxinterval=10.0, miniters=None, ascii=None, disable=False, unit='it', unit_scale=False, dynamic_ncols=False, smoothing=0.3, bar_format=None, initial=0, position=None, postfix=None, unit_divisor=1000, write_bytes=None, lock_args=None, nrows=None, colour=None, delay=0, gui=False, **kwargs)
  • iterable: iterable, optional
    可迭代对象,当手动跟新时不设置。
  • desc:str, optional
    进度条前的说明文字。
  • total:int or float, optional
    预期的迭代次数。如果未指定,则使用len(iterabel)
  • leave:bool, optional
    是否在迭代结束时保留进度条的所有痕迹,默认为True。
  • file:io.TextIOWrapper or io.StringIO, optional
    指定输出的进度信息的位置,默认为终端。
  • ncols:int, optional
    设置整个输出信息的宽度。如果指定,则动态调整进度条的大小以保持在此范围内。如果未指定,则尝试使用环境宽度。如果为0,将不会打印任何信息(只有统计数据)。
  • unit:str, optional
    用于定义每次迭代的单位的字符串(默认值:it)。
  • unit_scale:bool or int or float, optional
    如果为1或True,迭代次数将自动减少/缩放,并添加符合国际单位制标准的公制前缀(kilo、mega等)(默认为False)。如果任何其他非零数字,将对total和n缩放。
  • dynamic_ncols:bool, optional
    不断地改变ncols和nrows的环境(允许窗口调整大小)(默认为False]).
  • position:int, optional
    指定打印进度条的行偏移量(从0开始)。如果未指定,则自动设置。有助于同时管理多个进度条(例如多线程)。
  • postfix:dict or \, optional*
    指定在进度条末尾显示的其他统计信息。最好调用set_postfix(**postfix)
  • nrows:int, optional
    屏幕高度。
  • colour:str, optional
    进度条颜色,例如绿色使用#00ff00
  • delay:float, optional
    直到(默认0)秒后显示。

update

def update(n=1)

手动更新进度条,例如读取文件流。在手动跟新时,最好使用tqdm.close()with as语句。

  • n: int or float, optional
    添加到迭代内部计数器的增量(默认是1)。

close

def close()

清除并(如果leave=False)关闭进度条。

clear

def clear(nolock=False)

清除当前进度条显示。

refresh

def refresh(nolock=False, lock_args=None)

强制刷新进度条。

  • nolock: bool, optional
    If True, does not lock. If [default: False]: calls acquire() on internal lock.
  • lock_args: tuple, optional
    Passed to internal lock’s acquire(). If specified, will only display() if acquire() returns True.

unpause

def unpause()

从上次打印时间开始重启tqdm定时器。

reset

def reset(total=None)

将迭代器重置为0,结合leave=True使用。

  • total: int or float, optional. Total to use for the new bar.

set_descriptionset_description_str

def set_description(desc=None, refresh=True)
def set_description_str(desc=None, refresh=True)

设置/修改进度条的说明文字,_str的区别仅在于不添加“:”

  • desc: str, optional
  • refresh: bool, optional
    Forces refresh [default: True].

set_postfixset_postfix_str

def set_postfix(ordered_dict=None, refresh=True, **kwargs)
def set_postfix_str(s='', refresh=True)

设置/修改后缀,并且自动格式化输入的数据类型。_str不使用字典扩展,仅添加字符串。

  • *ordered_dict**: dict or OrderedDict, optional*
  • *refresh**: bool, optional*
    Forces refresh [default: True].
  • *kwargs**: dict, optional*

trang

def trange(*args, **kwargs)

tqdm(xrange(*args),* *kwargs)的快捷方法。在 Python3+ 上使用 range 而不是 xrange

使用示例

1. 指定迭代次数

from tqdm import tqdm, trange
import time

# 方法一:使用trange()
for i in trange(100):
    # 延时0.1秒
    time.sleep(0.1)
# 方法二:使用tqdm(range()),并添加说明文字
for i in tqdm(range(100), desc='Processing'):
    time.sleep(0.1)

>>> 100%|██████████| 100/100 [00:10<00:00,  9.91it/s]
>>> Processing: 100%|██████████| 100/100 [00:10<00:00,  9.91it/s]

2. 基于可迭代对象

from tqdm import tqdm
import time

dic = ['a', 'b', 'c', 'd', 'e']
pbar = tqdm(dic)
for i in pbar:
    pbar.set_description(f'Processing {i}')
    pbar.set_postfix(dic=i)
    time.sleep(0.5)

>>> Processing e: 100%|██████████| 5/5 [00:02<00:00,  1.99it/s, dic=e]

3. 手动更新

from tqdm import tqdm
import time

# 不传入可迭代对象而设置total参数,并使用update更新迭代值。
with tqdm(total=100) as pbar:
    for i in range(10):
        time.sleep(0.1)
        pbar.update(10)

        pbar.set_description(f'Processing {i}')
        pbar.set_postfix(total_ratio = i/10)

总结

读了一遍文档,觉得tqdm还是很易于使用的,几乎所有地迭代循环中都可无障碍嵌入。本文浅尝辄止地介绍了tqdm用于装饰迭代器进度条的标准使用方法,其他诸如在IPython/Jupyter Notebook、异步进度条、GUI等使用方法,等到本人更多使用后再作记录吧。


Author: yangli
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source yangli !
  TOC