讓你的程式炫起來!少有人知道但超酷的 Python 進度條開源庫

削微寒發表於2021-04-09

本文適合有 Python 基礎的朋友

本文作者:HelloGitHub-Anthony

HelloGitHub 推出的《講解開源專案》系列,本期介紹讓你快速擁有完美進度條的 Python 三方庫——alive-progress

專案地址:https://github.com/rsalmei/alive-progress

不知你是否有過這樣的經歷:你寫了一個程式,每次執行都會耗費很長時間。在等待程式執行期間你一次次的按下回車防止程式卡死。亦或者你的任務需要實時掌握程式執行進度但你根本不知道程式執行到了哪裡...

現在,alive-progress 來了,它是一個 Python 下的進度條庫,不僅使用方便而且支援多種炫酷顯示效果!讓我們先來看看示例效果:

下面讓我們一起玩轉這個庫!

一、安裝

在 Python 下使用 pip 進行安裝:

pip install alive-progress

二、快速入門

2.1 直接使用

在迴圈中使用 alive-progress 是最常見的用法,指令碼可以這樣寫:

# 匯入 alive-progress 庫
from alive_progress import alive_bar
import time

# 使用 with 語句建立一個進度條
with alive_bar(100) as bar:	# 給 alive_bar 傳入進度條總數目(這裡是 100)
    for item in range(100):
        # 等待 1s
        time.sleep(.1)
        #更新進度條,進度 +1
        bar()

請注意,如果無法正常顯示動畫則嘗試在 alive_bar 中加上 force_tty=True 引數。

執行以上程式碼我們可以看到在終端中出現了一個還算華麗的動態進度條:

需要注意的是 alive-progress 並不像 tqdm 等進度條庫一樣會自動更新,只有我們程式呼叫了 bar 才會讓進度條 +1.

當然,我們也可以不給進度條傳入總數目這個引數,此時進度條將不顯示進度,並進入未定義模式:

有時候我們想直接操縱顯示的位置,這時候可以設定 alive_barmanual 引數為 True

from alive_progress import alive_bar
import time

total = 100
with alive_bar(total, manual=True) as bar:	# total 可以不指定,這時候只有百分比
    bar(0.5) # 進度到 50%
    time.sleep(0.5)
    bar(0.1) # 進度到 10% 
    time.sleep(0.5)
    bar(0.75) # 進度到 75%
    time.sleep(0.5)
    bar(1.0) # 進度到 100%
    time.sleep(0.5)
    bar(10) # 進度到 1000%
    for i in range(1,101):
        bar(i/100) # 設定進度為 i%
        time.sleep(0.05)

當然,在執行過程中我們也需要輸出一些提示資訊,直接使用 print 可以在不破壞進度條的情況下輸出一行提示資訊,text 方法則可以在進度條尾部新增字尾字元,而 title 引數則可以給進度條新增標題(字首資訊),具體使用方法及效果如下:

from alive_progress import alive_bar
import time

# 定義標題(字首字元)為 HelloGitHub
with alive_bar(10, title="HelloGitHub") as bar:
    for i in range(10):
        time.sleep(1)

        bar()   # 讓進度 +1
        bar.text("Processing Work #%d"%(i+1))   # 更新進度條字尾

        print("Work #%d finished"%i)        # 輸出一行資訊

2.2 添點花樣

看多了傳統的進度條樣式想換換花樣?沒問題,alive-progress 不僅內建了多種進度條樣式,還支援自定義格式。

進度條可以自定義的樣式分為兩種:barspinner,只需要在呼叫 alive_bar 的時候傳入對應的引數即可。

以這個進度條為例,中間最長的是 bar,旁邊來回晃動的 www.HelloGitHub.comspinner

alive-progress 內建了多種 bar 和 spinner 樣式,只需要呼叫 show_bars 或者 show_spinners 即可快速預覽相應的樣式,例如:

from alive_progress import show_bars

show_bars() # 檢視內建 bar 樣式

from alive_progress import show_spinners

show_spinners() # 檢視內建 spinner 樣式

預設樣式使用起來非常簡單,例如我想使用 bubbles 這個 bar 和 message_scrolling 這個 spinner,直接傳入對應名稱即可:

from alive_progress import alive_bar
import time

# 直接傳入對應名字即可
with alive_bar(
            100,
            title="HelloGitHub", 
            bar="bubbles", spinner="message_scrolling"
            ) as bar:

    for i in range(100):
        time.sleep(.1)
        bar()

如果不知道 total 的數目,可以使用 unknown 引數(這時候將替換 bar 為 spinner):

from alive_progress import alive_bar
import time

with alive_bar(
            title="HelloGitHub", 
            # 注意:這裡 bar 被換成了unknow,內建樣式名稱與 spinner 的相同
            unknown="stars", spinner="message_scrolling"
            ) as bar:

    for i in range(100):
        time.sleep(.1)
        bar()

三、私人定製

或許比起直接使用內建模板你更喜歡自己定製的進度條,對此 alive-progress 也提供了對應方法。

3.1 定製 bar

使用 standard_bar_factory 方法可以快速定製 bar,bar 可以設定的引數有五個:

  • chars:正在執行單元的動畫,按照進度依次顯示。
  • borders:進度條邊界,顯示在左右兩邊。
  • background:未執行到單元顯示的內容。
  • tip:執行單元的前導符號。
  • errors:出錯時(進度未走全,超出 total 值等)時顯示的字元。

例如我們想做一個如圖所示的 bar:

則可以這樣來寫:

from alive_progress import alive_bar, standard_bar_factory
import time

##-------自定義 bar-------##
my_bar = standard_bar_factory(	# 以下引數均有預設值,不必一次全部修改
                            chars="123456789#", # 載入時根據進度依次顯示,長度任意
                            borders="<>",		# bar 兩頭的邊界
                            background=".",		# 未載入部分用 "." 填充
                            tip=">",			# 指示進度方向的引導符號(分割 "#" 與 ".")
                            errors="⚠❌" # 發生錯誤時顯示的內容(未完成,溢位)	
                            )
##-------自定義結束-------##

##--------動畫演示-------##
with alive_bar(
            10,
            title="HelloGitHub", 
            bar=my_bar, # 這裡傳入剛剛自定義的 bar
    		spinner="message_scrolling",
            manual=True
            ) as bar:

    for i in range(50):
        time.sleep(.1)
        bar(i/100)
    bar(.5)
    time.sleep(2)
    bar(10)
    print("上溢")
    time.sleep(1)
    bar(1)
    print("100% 完成")
    time.sleep(1)
    bar(.1)
    print("未完成")

3.2 定製 spinner

對於 spinner,alive-progress 提供了更多種的動畫定義方式:

frame_spinner_factory:將傳入的字串挨個輸出:

from alive_progress import alive_bar, frame_spinner_factory
import time

my_spinner = my_spinner = frame_spinner_factory(
                                r'-----',
                                r'1----',
                                r'-2---',
                                r'--3--',
                                r'---4-',
                                r'----5'
                                )	# 直接傳入字串

with alive_bar(
            title="HelloGitHub",
            spinner=my_spinner
            ) as bar:

    while True:
        bar()
        time.sleep(.1)

可以看到字串挨個迴圈輸出。

scrolling_spinner_factory:將字串滾動播出

from alive_progress import alive_bar, scrolling_spinner_factory
import time

my_spinner = scrolling_spinner_factory(
                                    chars="HelloGitHub", # 想要播放的字串
                                    length=15,	# spinner 區域寬度
                                    blank='.'	# 空白部分填充字元
                                    )

with alive_bar(
            title="HelloGitHub",
            spinner=my_spinner
            ) as bar:

    while True:
        bar()
        time.sleep(.1)

bouncing_spinner_factory:將兩個字串交替滾動播出

from alive_progress import alive_bar, bouncing_spinner_factory
import time

my_spinner = bouncing_spinner_factory(
                                    right_chars="I love", # 從左邊進入的字串
                                    length=15, # spinner 區域長度
                                    left_chars="HelloGitHub", # 從右邊進入的字串
                                    blank='.', 	# 空白區域填充字元
                                    )

with alive_bar(
            title="HelloGitHub",
            spinner=my_spinner
            ) as bar:

    while True:
        bar()
        time.sleep(.1)

當然,也可以省略 left_chars 這個引數,其效果相當於 I love 將會像彈球一樣左右彈動。

unknown_bar_factory:將 spinner 轉換為能使用在未定義模式中的格式:

from alive_progress import alive_bar, unknown_bar_factory, bouncing_spinner_factory
import time

my_spinner = bouncing_spinner_factory("www.HelloGitHub.com",15,hiding=False)

my_unknown_bar = unknown_bar_factory(my_spinner)	# 傳入定義的 spinner
with alive_bar(
            title="HelloGitHub",
            unknown=my_unknown_bar
            ) as bar:

    while True:
        bar()
        time.sleep(.1)

四、結尾

到這裡,相信你已經掌握了 alive_progress 的基本玩法,alive-progress 還提供了一些在不同場合所需的特殊功能,有興趣的朋友可以通過閱讀官方文件或原始碼進行更加深入的瞭解。本次的內容就到這裡了,快去建立一個屬於自己的進度條吧!


關注 HelloGitHub 公眾號 收到第一時間的更新。

還有更多開源專案的介紹和寶藏專案等待你的發掘。

相關文章