原文地址:

https://blog.ernest.me/post/python-progress-bar

tqdm

最近一款新的进度条 tqdm 库比较热门,声称比老版的 python-progressbar 库的单次响应时间提高了 10 倍以上。

Overhead is low -- about 60ns per iteration (80ns with gui=True). By comparison, the well established ProgressBar has an 800ns/iter overhead.

初读其源码,组织结构明显继承 python-progressbar,只是主代码行数从 357 提升到了 614。10 倍性能提升的奥妙在哪里呢?
在解答这个问题之前,我想先用这篇文章介绍下进度条的原理,然后,根据原理用几行代码实现一个简单的进度条。

progress bar 的原理

其实进度条的原理十分的简单,无非就是在 shell 中不断重写当前输出。
这时就不得不提到文本系统中的控制符。我们挑跟这次有关的看一下。

  • \r = CR (Carriage Return) // moves the cursor to the beginning of the line without advancing to the next line(该控制符告诉输出端,将光标移到当前行的首位而不换行)
  • \n = LF (Line Feed) // moves the cursor down to the next line without returning to the beginning of the line - *In a nix environment \n moves to the beginning of the line.(传统意义上的换行符,将光标移到下一行,但_并不移到首位_ )
  • \r\n = CR + LF // a combi of \r and \n (换行并移动光标到行首)

这时,想要实现一个进度条,就十分简单,看下方代码。

Bash 实现

#/usr/bin/bash
for i in {..};
do
echo -ne "$i% \r"
sleep 0.01
done
echo -ne "\n"

但是,echo -n 存在明显的兼容性问题。

-n Do not print the trailing newline character. This may also be achieved by appending \c to the end of the string, as is done by iBCS2 compatible systems. Note that this option as well as the effect of \c are implementation-defined in IEEE Std 1003.1-2001 (POSIX.1) as amended by Cor. 1-2002. Applications aiming for maximum portability are strongly encouraged to use printf(1) to suppress the newline character.

Some shells may provide a builtin echo command which is similar or identical to this utility. Most notably, the builtin echo in sh(1) does not accept the -n option. Consult the builtin(1) manual page.

推荐使用 printf

#/usr/bin/bash
for i in {..};
do
printf "%s%% \r" $i
sleep 0.01
done
printf "\n"

Python 实现

Python 主要使用系统库里的标准输出,sys.stdout 提供了便利的方法用于向 shell 打印输出。具体的方法介绍这里不赘述。

import sys
import time for i in range(100):
sys.stdout.write(' \r')
sys.stdout.flush()
sys.stdout.write('{}%\r'.format(i))
sys.stdout.flush()
time.sleep(0.01)

References

从 Python 第三方进度条库 tqdm 谈起 (转载)的更多相关文章

  1. Python - 进度条库 tqdm

    前言 在写生成器的时候,网上看到一个进度条库,感觉蛮有意思,记录下 这个库感觉只有在调试的时候会用到,不做深入学习 内置库,不需要安装 示例代码 from tqdm import tqdm for i ...

  2. 一个简单、易用的Python命令行(terminal)进度条库

    eprogress 是一个简单.易用的基于Python3的命令行(terminal)进度条库,可以自由选择使用单行显示.多行显示进度条或转圈加载方式,也可以混合使用. 示例 单行进度条 多行进度条 圆 ...

  3. Python进度条模块tqdm实现任务进度可视化

    一.前言 tqdm 是一个易用性强.扩展性高的 Python 进度条库,可以在 Python 长循环中添加一个进度提示信息,我们只需要封装任意的迭代器 tqdm(iterator) 即可. 二.安装 ...

  4. python 中有趣的库tqdm

    Tqdm 是 Python 进度条库,可以在 Python 长循环中添加一个进度提示信息用法:tqdm(iterator) # 方法1: import time from tqdm import tq ...

  5. Python实现进度条和时间预估的示例代码

    一.前言 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人,我给大家 ...

  6. Python字符进度条

    Python字符进度条 看看这个神奇的module from tqdm import trange from time import sleep for r in trange(10, 1, -1): ...

  7. Python之进度条及π的计算

    Python之进度条及π的计算 文本进度条 1.  简单的开始 这是利用print()函数来实现简单的非刷新文本进度条.它的基本思想是按照任务执行百分比将整个任务划分为100个单位,每执行N%输出一次 ...

  8. Python实现进度条功能

    Python实现进度条功能 import sys, time def progress(percent, width=50): # 设置进度条的宽度 if percent >= 100: # 当 ...

  9. 自主学习python文本进度条及π的计算

    经过自己一段时间的学习,已经略有收获了!在整个过程的进行中,在我逐渐通过看书,看案例,做题积累了一些编程python的经验以后,我发现我渐渐爱上了python,爱上了编程! 接下来,当然是又一些有趣的 ...

随机推荐

  1. python 元组元素反转

    #create a tuple x = ("w3resource") # Reversed the tuple y = reversed(x) print(tuple(y)) #c ...

  2. Android JNI学习(三)——Java与Native相互调用

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  3. idea忽略文件

  4. C#读写记事本(txt)文件

    C#写入记事本(txt)文件方法一: FileStream stream = new FileStream(@"d:\aa.txt",FileMode.Create);//file ...

  5. python-day33--进程间通信(IPC)

    方式:队列(推荐使用) 一.基本情况 1.可以往队列里放任意类型的数据 2. 队列:先进先出 3. q=Queue(3) #可以设置队列中最多可以进入多少个值,也可以不设置 q.put('first' ...

  6. linux进程原语之fork()

    一.用法解析: fork()这个函数,可以说是名如其人了,众所周知fork这个单词本意为叉子,老外取学术名字的时候总会有一些象形的想法,于是就有了下图~ fork()函数是计算机程序设计中的分叉函数. ...

  7. nyoj 1238(BFSor最短路)

    最少换乘 时间限制:2000 ms  |  内存限制:65535 KB 难度:3   描述 欧洲某城是一个著名的旅游胜地,每年都有成千上万的人前来观光旅行.Dr. Kong决定利用暑假好好游览一番.. ...

  8. POJ-3414 Pots (BFS)

    Description You are given two pots, having the volume of A and B liters respectively. The following ...

  9. 新建 ASP.NET MVC 项目快速代码

    视图模型- PagingInfo 类: public class PagingInfo { public int TotalItems { get; set; } public int ItemsPe ...

  10. bind出现Address already in use解决方法

    在socket函数和bind函数之间加入一段代码: // 建立服务器端socket if((server_sockfd = socket(AF_INET, SOCK_STREAM, 0))<0) ...