【導讀】:有的 Python 程序較大,執行須要花費較長的時間,有的用戶在「盲目」地等待運行結果,但又不能明確知道程序進展到什麼程度的時候,頗有可能因心情急躁而終止程序。python
本文介紹的這個有着 1.7 萬 Star 的開源庫,就能解決這個煩惱。git
https://github.com/tqdm/tqdmgithub
使用 Python Tqdm 進度條庫,可讓 python 程序執行進度可視化。算法
在阿拉姆語(Aramaic)、希伯來語(Hebrew)、和阿拉伯語(Arabic)中,閃米特語(Semitic)詞根q-d-m
一般與前進
或取得進步
的意思掛鉤。例如,阿拉伯語單詞 taqaddum (تقدّم) 的意思是「進步」。進步是重要的,就像每一部使人愉悅的電影都會向你傳達一個哲理——旅途和目的地同樣重要。
大多數程序都有一個明確目標,那就是程序運行的最終(結束)狀態,成功仍是失敗!可是每每有時候程序的運行可能須要很長時間。儘管計算機沒有情感,不在意程序執行時間的長短,但是人們是在意的。網絡
隨着時間推移,程序運行人員或用戶的疑問會不斷蔓延(程序崩潰了嗎?磁盤跳動了嗎?操做系統是否將全部計算資源分配給了其餘任務?)當程序運行過程當中長時間沒有任何的進展跡象時,程序運行人員可能會疑慮、煩躁,不肯意繼續等待下去。而本文講的 tqdm 庫便有助於明確顯示程序的執行進度。dom
tqdm 庫模塊能夠在命令控制檯一塊兒使用,可是也支持我最喜歡的開發環境之一的 Jupyter notebook。若是想在 Jupyter notebook 中使用 tqdm,notebook 模塊與 tqdm 接口兼容,須要導入 notebook 子模塊並安裝ipywidget
。url
這就意味着你能夠在導入 tqdm 庫操做以前作一下條件判斷,這個判斷方法是檢查_main_
模塊中是否有get_ipython
全局變量。雖然上面這個判斷導庫方法是一個啓發式的,但它是一個至關準確的方法:spa
import sys if hasattr(sys.modules["__main__"],"get_ipython"): from tqdm import notebook as tqdm else: import tqdm
舉個最簡單的狀況來助於理解一下,某程序須要執行必定數量的迭代(迭代次數預先可知),可是這些迭代中的每一次迭代花費大約相同的時間。例如,一個能夠計算任意數字平方根的算法,算法是從1開始,而後計算一個進度估計。操作系統
def improve_guess(rt, n): return (rt + n/rt) / 2
對以上代碼的少量改進可讓你更容易理解:3d
guess = 1 target = 2 for i in tqdm.trange(10): guess = improve_guess(guess, target)
精確到小數點後十位:
round(2 - guess*guess, 10) 0.0
再舉一個稍微複雜的tqdm例子,當處理的元素數量已知且計算每一個元素的時間類似。例如,計算一些隨機數字的伺機:
import random numbers = [random.uniform(0, 2.8) for i in range(100)] numbers[:5] [2.6575636572230916, 0.1286674965830302, 1.0634250104041332, 1.1760969844376505, 0.45192978568125486]
數值元素有了,接下來使用tqdm顯示進度條,使用tqdm最簡單的方法是封裝Python中可迭代的對象。
result = 1 for num in tqdm.tqdm(numbers): result *= num result 2.4081854901728303
可是,不是全部的事情都是可預測的,其中不可預測的事情之一是網絡速度。下載大文件時,衡量進度的惟一的方法是顯示已經下載了多少文件:
url = "https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz" import httpx with httpx.stream("GET", url) as response: total = int(response.headers["Content-Length"]) with tqdm.tqdm(total=total) as progress: for chunk in response.iter_bytes(): progress.update(len(chunk))
有時,「嵌套」進度條是有意義的。例如,若是正在下載一個目錄,則須要一個跟蹤文件的進度條和每一個文件的進度條。
下面是一個示例(但沒有實際下載目錄):
files = [f"vid-{i}.mp4" for i in range(4)] for fname in tqdm.tqdm(files, desc="files"): total = random.randrange(10**9, 2 * 10**9) with tqdm.tqdm(total=total, desc=fname) as progress: current = 0 while current < total: chunk_size = min(random.randrange(10**3, 10**5), total - current) current += chunk_size if random.uniform(0, 1) < 0.01: time.sleep(0.1) progress.update(chunk_size)
所以,若是你的程序須要一段時間才能顯示最終結果,爲了不用戶感到沮喪:顯示它的進度狀況!
開源前哨
平常分享熱門、有趣和實用的開源項目。參與維護 10萬+ Star 的開源技術資源庫,包括:Python、Java、C/C++、Go、JS、CSS、Node.js、PHP、.NET 等。