python的Tqdm模块

Tqdm 是一个快速,可扩展的Python进度条,可以在 python 长循环中添加一个进度提示信息,用户只需要封装任意的迭代器 tqdm(iterator)。

我的系统是window环境,首先安装python,接下来就是pip。

pip安装:

在python根目录下创建一个get-pip.py的文件,内容:

[python] view plain copy
  1. https://bootstrap.pypa.io/get-pip.py  
然后在CMD窗口进入python下面:

输出:

[python] view plain copy
  1. python -m pip install -U pip  
由于Tqdm要求的pip版本是9.0所以需要手动安装pip9.0

http://pypi.python.org/pypi/pip

下载安装包9.0

然后解压进入,CMD窗口输入:python setup.py install

然后就可以安装Tqdm了,

[python] view plain copy
  1. pip install tqdm  
安装最新的开发版的话
[python] view plain copy
  1. pip install -e git+https://github.com/tqdm/tqdm.git@master#egg=tqdm  
最后看看怎么用呢?https://pypi.python.org/pypi/tqdm

基本用法:

[python] view plain copy
  1. from tqdm import tqdm  
  2. for i in tqdm(range(10000)):  
  3.      sleep(0.01)  
当然除了tqdm,还有trange,使用方式完全相同
[python] view plain copy
  1. for i in trange(100):  
  2.         sleep(0.1)  
只要传入list都可以:
[python] view plain copy
  1. pbar = tqdm(["a""b""c""d"])  
  2. for char in pbar:  
  3.     pbar.set_description("Processing %s" % char)  
也可以手动控制更新
[python] view plain copy
  1. with tqdm(total=100) as pbar:  
  2.     for i in range(10):  
  3.         pbar.update(10)  
也可以这样:
[python] view plain copy
  1. pbar = tqdm(total=100)  
  2. for i in range(10):  
  3.     pbar.update(10)  
  4. pbar.close()  
在Shell的tqdm用法

统计所有python脚本的行数:

[python] view plain copy
  1. $ time find . -name '*.py' -exec cat \{} \; | wc -l  
  2. 857365  
  3.   
  4. real    0m3.458s  
  5. user    0m0.274s  
  6. sys     0m3.325s  
  7.   
  8. $ time find . -name '*.py' -exec cat \{} \; | tqdm | wc -l  
  9. 857366it [00:03246471.31it/s]  
  10. 857365  
  11.   
  12. real    0m3.585s  
  13. user    0m0.862s  
  14. sys     0m3.358s  
使用参数:
[python] view plain copy
  1. $ find . -name '*.py' -exec cat \{} \; |  
  2.     tqdm --unit loc --unit_scale --total 857366 >> /dev/null  
  3. 100%|███████████████████████████████████| 857K/857K [00:04<00:00246Kloc/s]  
备份一个目录:
[python] view plain copy
  1. 7z a -bd -r backup.7z docs/ | grep Compressing |  
  2.     tqdm --total $(find docs/ -type f | wc -l) --unit files >> backup.log  
  3. 100%|███████████████████████████████▉| 8014/8014 [01:37<00:0082.29files/s]  
通过看示范的代码,我们能发现使用的核心是tqdm和trange这两个函数,从代码层面分析tqdm的功能,那首先是init.py
[python] view plain copy
  1. __all__ = ['tqdm''tqdm_gui''trange''tgrange''tqdm_pandas',  
  2.            'tqdm_notebook''tnrange''main''TqdmKeyError''TqdmTypeError',  
  3.            '__version__']  
跟踪到_tqdm.py,能看到tqdm类的声明,首先是初始化
[python] view plain copy
  1. def __init__(self, iterable=None, desc=None, total=None, leave=True,  
  2.                  file=sys.stderr, ncols=None, mininterval=0.1,  
  3.                  maxinterval=10.0, miniters=None, ascii=None, disable=False,  
  4.                  unit='it', unit_scale=False, dynamic_ncols=False,  
  5.                  smoothing=0.3, bar_format=None, initial=0, position=None,  
  6.                  gui=False, **kwargs):  
[python] view plain copy
  1. Parameters  
  2.   
  3. iterable : iterable, optional  
  4. Iterable to decorate with a progressbar.  
  5. 可迭代的进度条。  
  6. Leave blank to manually manage the updates.  
  7. 留空手动管理更新??  
  8. desc : str, optional  
  9. Prefix for the progressbar.  
  10. 进度条的描述  
  11. total : int, optional  
  12. The number of expected iterations. If unspecified,  
  13. len(iterable) is used if possible. As a last resort, only basic  
  14. progress statistics are displayed (no ETA, no progressbar).  
  15. If gui is True and this parameter needs subsequent updating,  
  16. specify an initial arbitrary large positive integer,  
  17. e.g. int(9e9).  
  18. 预期的迭代数目,默认为None,则尽可能的迭代下去,如果gui设置为True,这里则需要后续的更新,将需要指定为一个初始随意值较大的正整数,例如int(9e9)  
  19. leave : bool, optional  
  20. If [default: True], keeps all traces of the progressbar  
  21. upon termination of iteration.  
  22. 保留进度条存在的痕迹,简单来说就是会把进度条的最终形态保留下来,默认为True  
  23. file : io.TextIOWrapper or io.StringIO, optional  
  24. Specifies where to output the progress messages  
  25. [default: sys.stderr]. Uses file.write(str) and file.flush()  
  26. methods.  
  27. 指定消息的输出  
  28. ncols : int, optional  
  29. The width of the entire output message. If specified,  
  30. dynamically resizes the progressbar to stay within this bound.  
  31. If unspecified, attempts to use environment width. The  
  32. fallback is a meter width of 10 and no limit for the counter and  
  33. statistics. If 0, will not print any meter (only stats).  
  34. 整个输出消息的宽度。如果指定,动态调整的进度停留在这个边界。如果未指定,尝试使用环境的宽度。如果为0,将不打印任何东西(只统计)。  
  35. mininterval : float, optional  
  36. Minimum progress update interval, in seconds [default: 0.1].  
  37. 最小进度更新间隔,以秒为单位(默认值:0.1)。  
  38. maxinterval : float, optional  
  39. Maximum progress update interval, in seconds [default: 10.0].  
  40. 最大进度更新间隔,以秒为单位(默认值:10)。  
  41. miniters : int, optional  
  42. Minimum progress update interval, in iterations.  
  43. If specified, will set mininterval to 0.  
  44. 最小进度更新周期  
  45. ascii : bool, optional  
  46. If unspecified or False, use unicode (smooth blocks) to fill  
  47. the meter. The fallback is to use ASCII characters 1-9 #.  
  48. 如果不设置,默认为unicode编码  
  49. disable : bool, optional  
  50. Whether to disable the entire progressbar wrapper  
  51. [default: False].  
  52. 是否禁用整个进度条包装(如果为True,进度条不显示)  
  53. unit : str, optional  
  54. String that will be used to define the unit of each iteration  
  55. [default: it].  
  56. 将被用来定义每个单元的字符串???  
  57. unit_scale : bool, optional  
  58. If set, the number of iterations will be reduced/scaled  
  59. automatically and a metric prefix following the  
  60. International System of Units standard will be added  
  61. (kilo, mega, etc.) [default: False].  
  62. 如果设置,迭代的次数会自动按照十、百、千来添加前缀,默认为false  
  63. dynamic_ncols : bool, optional  
  64. If set, constantly alters ncols to the environment (allowing  
  65. for window resizes) [default: False].  
  66. 不断改变ncols环境,允许调整窗口大小  
  67. smoothing : float, optional  
  68. Exponential moving average smoothing factor for speed estimates  
  69. (ignored in GUI mode). Ranges from 0 (average speed) to 1  
  70. (current/instantaneous speed) [default: 0.3].  
  71.   
  72. bar_format : str, optional  
  73. Specify a custom bar string formatting. May impact performance.  
  74. If unspecified, will use ‘{l_bar}{bar}{r_bar}’, where l_bar is  
  75. ‘{desc}{percentage:3.0f}%|’ and r_bar is  
  76. ‘| {n_fmt}/{total_fmt} [{elapsed_str}<{remaining_str}, {rate_fmt}]’  
  77. Possible vars: bar, n, n_fmt, total, total_fmt, percentage,  
  78. rate, rate_fmt, elapsed, remaining, l_bar, r_bar, desc.  
  79. 自定义栏字符串格式化…默认会使用{l_bar}{bar}{r_bar}的格式,格式同上  
  80.   
  81. initial : int, optional  
  82. The initial counter value. Useful when restarting a progress  
  83. bar [default: 0].  
  84. 初始计数器值,默认为0  
  85. position : int, optional  
  86. Specify the line offset to print this bar (starting from 0)  
  87. Automatic if unspecified.  
  88. Useful to manage multiple bars at once (eg, from threads).  
  89. 指定偏移,这个功能在多个条中有用  
  90. gui : bool, optional  
  91. WARNING: internal parameter - do not use.  
  92. Use tqdm_gui(…) instead. If set, will attempt to use  
  93. matplotlib animations for a graphical output [default: False].  
  94. 内部参数…  
  95. Returns  
  96. out : decorated iterator.  
  97. 返回为一个迭代器  

其实不用分析更多代码,多看看几个例子:(官网的例子)

7zx.py压缩进度条

[python] view plain copy
  1. # -*- coding: utf-8 -*-  
  2. """Usage: 
  3.   7zx.py [--help | options] ... 
  4. Options: 
  5.   -h, --help     Print this help and exit 
  6.   -v, --version  Print version and exit 
  7.   -c, --compressed       Use compressed (instead of uncompressed) file sizes 
  8.   -s, --silent   Do not print one row per zip file 
  9.   -y, --yes      Assume yes to all queries (for extraction) 
  10.   -D=, --debug= 
  11.                  Print various types of debugging information. Choices: 
  12.                          CRITICAL|FATAL 
  13.                          ERROR 
  14.                          WARN(ING) 
  15.                          [default: INFO] 
  16.                          DEBUG 
  17.                          NOTSET 
  18.   -d, --debug-trace      Print lots of debugging information (-D NOTSET) 
  19. """  
  20. from __future__ import print_function  
  21. from docopt import docopt  
  22. import logging as log  
  23. import subprocess  
  24. import re  
  25. from tqdm import tqdm  
  26. import pty  
  27. import os  
  28. import io  
  29. __author__ = "Casper da Costa-Luis "  
  30. __licence__ = "MPLv2.0"  
  31. __version__ = "0.2.0"  
  32. __license__ = __licence__  
  33.   
  34.   
  35. RE_SCN = re.compile("([0-9]+)\s+([0-9]+)\s+(.*)$", flags=re.M)  
  36.   
  37.   
  38. def main():  
  39.     args = docopt(__doc__, version=__version__)  
  40.     if args.pop('--debug-trace'False):  
  41.         args['--debug'] = "NOTSET"  
  42.     log.basicConfig(level=getattr(log, args['--debug'], log.INFO),  
  43.                     format='%(levelname)s: %(message)s')  
  44.     log.debug(args)  
  45.   
  46.     # Get compressed sizes  
  47.     zips = {}  
  48.     for fn in args['']:  
  49.         info = subprocess.check_output(["7z""l", fn]).strip()  
  50.         finfo = RE_SCN.findall(info)  
  51.   
  52.         # builtin test: last line should be total sizes  
  53.         log.debug(finfo)  
  54.         totals = map(int, finfo[-1][:2])  
  55.         # log.debug(totals)  
  56.         for s in range(2):  
  57.             assert(sum(map(int, (inf[s] for inf in finfo[:-1]))) == totals[s])  
  58.         fcomp = dict((n, int(c if args['--compressed'else u))  
  59.                      for (u, c, n) in finfo[:-1])  
  60.         # log.debug(fcomp)  
  61.         # zips  : {'zipname' : {'filename' : int(size)}}  
  62.         zips[fn] = fcomp  
  63.   
  64.     # Extract  
  65.     cmd7zx = ["7z""x""-bd"]  
  66.     if args['--yes']:  
  67.         cmd7zx += ["-y"]  
  68.     log.info("Extracting from {:d} file(s)".format(len(zips)))  
  69.     with tqdm(total=sum(sum(fcomp.values()) for fcomp in zips.values()),  
  70.               unit="B", unit_scale=True) as tall:  
  71.         for fn, fcomp in zips.items():  
  72.             md, sd = pty.openpty()  
  73.             ex = subprocess.Popen(cmd7zx + [fn],  
  74.                                   bufsize=1,  
  75.                                   stdout=md,  # subprocess.PIPE,  
  76.                                   stderr=subprocess.STDOUT)  
  77.             os.close(sd)  
  78.             with io.open(md, mode="rU", buffering=1) as m:  
  79.                 with tqdm(total=sum(fcomp.values()), disable=len(zips) < 2,  
  80.                           leave=False, unit="B", unit_scale=True) as t:  
  81.                     while True:  
  82.                         try:  
  83.                             l_raw = m.readline()  
  84.                         except IOError:  
  85.                             break  
  86.                         l = l_raw.strip()  
  87.                         if l.startswith("Extracting"):  
  88.                             exname = l.lstrip("Extracting").lstrip()  
  89.                             s = fcomp.get(exname, 0)  # 0 is likely folders  
  90.                             t.update(s)  
  91.                             tall.update(s)  
  92.                         elif l:  
  93.                             if not any(l.startswith(i) for i in  
  94.                                        ("7-Zip ",  
  95.                                         "p7zip Version ",  
  96.                                         "Everything is Ok",  
  97.                                         "Folders: ",  
  98.                                         "Files: ",  
  99.                                         "Size: ",  
  100.                                         "Compressed: ")):  
  101.                                 if l.startswith("Processing archive: "):  
  102.                                     if not args['--silent']:  
  103.                                         t.write(t.format_interval(  
  104.                                             t.start_t - tall.start_t) + ' ' +  
  105.                                             l.lstrip("Processing archive: "))  
  106.                                 else:  
  107.                                     t.write(l)  
  108.             ex.wait()  
  109.   
  110.   
  111. main.__doc__ = __doc__  
  112.   
  113.   
  114. if __name__ == "__main__":  
  115.     main()  
tqdm_wget.py

[python] view plain copy
  1. """An example of wrapping manual tqdm updates for urllib reporthook. 
  2. # urllib.urlretrieve documentation 
  3. > If present, the hook function will be called once 
  4. > on establishment of the network connection and once after each block read 
  5. > thereafter. The hook will be passed three arguments; a count of blocks 
  6. > transferred so far, a block size in bytes, and the total size of the file. 
  7. Usage: 
  8.     tqdm_wget.py [options] 
  9. Options: 
  10. -h, --help 
  11.     Print this help message and exit 
  12. -u URL, --url URL  : string, optional 
  13.     The url to fetch. 
  14.     [default: http://www.doc.ic.ac.uk/~cod11/matryoshka.zip] 
  15. -o FILE, --output FILE  : string, optional 
  16.     The local file path in which to save the url [default: /dev/null]. 
  17. """  
  18.   
  19. import urllib  
  20. from tqdm import tqdm  
  21. from docopt import docopt  
  22.   
  23.   
  24. def my_hook(t):  
  25.     """ 
  26.     Wraps tqdm instance. Don't forget to close() or __exit__() 
  27.     the tqdm instance once you're done with it (easiest using `with` syntax). 
  28.     Example 
  29.     ------- 
  30.     >>> with tqdm(...) as t: 
  31.     ...     reporthook = my_hook(t) 
  32.     ...     urllib.urlretrieve(..., reporthook=reporthook) 
  33.     """  
  34.     last_b = [0]  
  35.   
  36.     def inner(b=1, bsize=1, tsize=None):  
  37.         """ 
  38.         b  : int, optional 
  39.             Number of blocks just transferred [default: 1]. 
  40.         bsize  : int, optional 
  41.             Size of each block (in tqdm units) [default: 1]. 
  42.         tsize  : int, optional 
  43.             Total size (in tqdm units). If [default: None] remains unchanged. 
  44.         """  
  45.         if tsize is not None:  
  46.             t.total = tsize  
  47.         t.update((b - last_b[0]) * bsize)  
  48.         last_b[0] = b  
  49.     return inner  
  50.   
  51.   
  52. opts = docopt(__doc__)  
  53.   
  54. eg_link = opts['--url']  
  55. eg_file = eg_link.replace('/'' ').split()[-1]  
  56. with tqdm(unit='B', unit_scale=True, leave=True, miniters=1,  
  57.           desc=eg_file) as t:  # all optional kwargs  
  58.     urllib.urlretrieve(eg_link, filename=opts['--output'],  
  59.                        reporthook=my_hook(t), data=None)  
examples.py
[python] view plain copy
  1. """ 
  2. # Simple tqdm examples and profiling 
  3. # Benchmark 
  4. for i in _range(int(1e8)): 
  5.     pass 
  6. # Basic demo 
  7. import tqdm 
  8. for i in tqdm.trange(int(1e8)): 
  9.     pass 
  10. # Some decorations 
  11. import tqdm 
  12. for i in tqdm.trange(int(1e8), miniters=int(1e6), ascii=True, 
  13.                      desc="cool", dynamic_ncols=True): 
  14.     pass 
  15. # Nested bars 
  16. from tqdm import trange 
  17. for i in trange(10): 
  18.     for j in trange(int(1e7), leave=False, unit_scale=True): 
  19.         pass 
  20. # Experimental GUI demo 
  21. import tqdm 
  22. for i in tqdm.tgrange(int(1e8)): 
  23.     pass 
  24. # Comparison to https://code.google.com/p/python-progressbar/ 
  25. try: 
  26.     from progressbar.progressbar import ProgressBar 
  27. except ImportError: 
  28.     pass 
  29. else: 
  30.     for i in ProgressBar()(_range(int(1e8))): 
  31.         pass 
  32. # Dynamic miniters benchmark 
  33. from tqdm import trange 
  34. for i in trange(int(1e8), miniters=None, mininterval=0.1, smoothing=0): 
  35.     pass 
  36. # Fixed miniters benchmark 
  37. from tqdm import trange 
  38. for i in trange(int(1e8), miniters=4500000, mininterval=0.1, smoothing=0): 
  39.     pass 
  40. """  
  41.   
  42. from time import sleep  
  43. from timeit import timeit  
  44. import re  
  45.   
  46. # Simple demo  
  47. from tqdm import trange  
  48. for i in trange(16, leave=True):  
  49.     sleep(0.1)  
  50.   
  51. # Profiling/overhead tests  
  52. stmts = filter(None, re.split(r'\n\s*#.*?\n', __doc__))  
  53. for s in stmts:  
  54.     print(s.replace('import tqdm\n'''))  
  55.     print(timeit(stmt='try:\n\t_range = xrange'  
  56.                       '\nexcept:\n\t_range = range\n' + s, number=1),  
  57.           'seconds')  
pandas_progress_apply.py
[python] view plain copy
  1. import pandas as pd  
  2. import numpy as np  
  3. from tqdm import tqdm  
  4.   
  5. df = pd.DataFrame(np.random.randint(0100, (1000006)))  
  6.   
  7. # Register `pandas.progress_apply` and `pandas.Series.map_apply` with `tqdm`  
  8. # (can use `tqdm_gui`, `tqdm_notebook`, optional kwargs, etc.)  
  9. tqdm.pandas(desc="my bar!")  
  10.   
  11. # Now you can use `progress_apply` instead of `apply`  
  12. # and `progress_map` instead of `map`  
  13. df.progress_apply(lambda x: x**2)  
  14. # can also groupby:  
  15. # df.groupby(0).progress_apply(lambda x: x**2)  
  16.   
  17.   
  18. # -- Source code for `tqdm_pandas` (really simple!)  
  19. # def tqdm_pandas(t):  
  20. #   from pandas.core.frame import DataFrame  
  21. #   def inner(df, func, *args, **kwargs):  
  22. #       t.total = groups.size // len(groups)  
  23. #       def wrapper(*args, **kwargs):  
  24. #           t.update(1)  
  25. #           return func(*args, **kwargs)  
  26. #       result = df.apply(wrapper, *args, **kwargs)  
  27. #       t.close()  
  28. #       return result  
  29. #   DataFrame.progress_apply = inner  
用tqdm并非强制作为依赖:

include_no_requirements.py

[python] view plain copy
  1. # How to import tqdm without enforcing it as a dependency  
  2. try:  
  3.     from tqdm import tqdm  
  4. except ImportError:  
  5.     def tqdm(*args, **kwargs):  
  6.         if args:  
  7.             return args[0]  
  8.         return kwargs.get('iterable'None)  

参考:
https://github.com/tqdm/tqdm/tree/master/examples

https://pypi.python.org/pypi/tqdm

https://github.com/tqdm/tqdm

你可能感兴趣的:(python)