Pythonで進捗表示といえばtqdmが有名だと思いますが、今回はlight-progressというライブラリを紹介したいと思います。
特徴
light-progress
は依存ライブラリを必要とせず軽量なライブラリを目指しており、Python2でも3でも動くようになっています。LinuxやMacではカラー表示に対応しており進行中・完了・エラー終了でそれぞれカラーが変わります。自分の環境では Jupyter Notebook でも動きました。
ただ light_progress
というようにモジュール名に _
が含まれているのがイケてなかったり関数名が微妙だったりというのは気になっています。ロードマップにはコマンドラインだけでなくGUIのためのツールやWindowsでのカラー表示があります。
インストール
pip install light-progress
使い方
from time import sleep
from light_progress.commandline import ProgressBar
1. 愚直な使い方
start()
で進捗管理を開始し、 forward()
もしくは update(i)
進捗を進めます。最後に finish()
を呼び出して終了します。これは最も直接的な使い方ですがかなり不便です。
n = 42
progress_bar = ProgressBar(n)
progress_bar.start()
for item in range(n):
sleep(0.01)
progress_bar.forward()
progress_bar.finish()
2. 1よりちょっと手間を省く
start()
や finish()
を自分で呼び出すのは面倒なので with
文を使って省略できます。
n = 42
with ProgressBar(n) as progress_bar:
for item in range(n):
sleep(0.01)
progress_bar.forward()
3. イテレーションをライブラリに移譲
2も面倒なのでイテレーションをライブラリに移譲できます。行いたい処理は引数で渡します。
ProgressBar.iteration(range(42), lambda item: sleep(0.01))
4. ジェネレータを使う
3はコードを短くできますが、引数に関数や lambda
を入れるのがあまり直感的ではありません。ジェネレータ関数を使ってイテレーション自体は移譲せずに forward()
など面倒な処理だけをライブラリ側に委ねます。これが最もシンプルで使いやすい形だと思われます。
for item in ProgressBar.generation(range(42)):
sleep(0.01)
表示のカスタマイズ
表示は widget
を使ってカスタマイズすることができます。各 widget
や文字列をリストにして widgets
として渡すと適応できます。
from light_progress import widget
widgets = [widget.Bar(bar='=', tip='-'),
widget.Percentage(),
widget.Num()]
ProgressBar.iteration(
range(42), lambda item: sleep(0.01), widgets=widgets)
# [===============-...............] 50% (21/42)
widgets = [widget.Percentage(),
widget.Num(),
'loading...',
widget.Bar(bar='#', tip='>')]
ProgressBar.iteration(
range(42), lambda item: sleep(0.01), widgets=widgets)
# 50% (21/42) loading... [###############>...............]
独自widget
progress_bar.widget.Widget
を継承してクラスを作り、 get_str
を実装すれば独自のwidgetが作成できます。 get_str
の context
には progress_bar.core.Progress
を継承したクラスのインスタンス( progress_bar.commandline.ProgressBar
など)が入ってくるので、それらのプロパティを表示項目に使用できます。
表示フォーマット
widget
で表示をカスタマイズできますが、format_str
に '{}'
の入った文字列を渡すことで各widget間や配置もカスタマイズできます。なお widgets
の項目数と format_str
に含まれる '{}'
の数は一致している必要があります。
format_str = '{} {} ({})'
widgets = [widget.Bar(), widget.Percentage(), widget.Num()]
ProgressBar.iteration(
range(100),
lambda item: sleep(0.01),
widgets=widgets,
format_str=format_str)
# [███████████████████████████████] 100% (100/100)
format_str = '{} *** {} *** ({})'
widgets = [widget.Bar(), widget.Percentage(), widget.Num()]
ProgressBar.iteration(
range(100),
lambda item: sleep(0.01),
widgets=widgets,
format_str=format_str)
# [███████████████████████████████] *** 100% *** (100/100)
くるくる回るやつ
ProgressBar
だけでなく Loading
くるくる回る表示もできます。
from light_progress.commandline import Loading
Loading.iteration(range(100), lambda item: sleep(0.01))
余談
ちなみにlight-progressはtqdmというものがあると知らなかったときに、自分の別プロジェクトで進捗管理していた部分を独立させてPyPIに公開したものです。せっかくなので育てて行きたいと思います。