Python逆引き:処理待ちの間に進捗表示したい(プログレスバーを出したい)

備忘録ヘッダ画像 逆引きソースコード

処理待ちの間に標準出力に進捗バー(プログレスバー)を表示するためには通常、プログレスバーをアップデートし、クリアして再描画する方法が使われる。

ここではターミナルに進捗バーを表示するために、自前で簡単な進捗バーを実装する例と、特定のモジュール(tqdm)を使用する例を記載しておく。

自前で進捗バーを出すコード

import time
import sys

# 進捗バーを表示する関数
def progress_bar(iterable, total=None, length=30):
    total = total or len(iterable)
    progress = 0

    for item in iterable:
        yield item
        progress += 1
        percent = progress / total
        fill_length = int(length * percent)
        bar = f"[{'=' * fill_length}{' ' * (length - fill_length)}] {percent:.1%}"
        sys.stdout.write('\r' + bar)
        sys.stdout.flush()

# 例として 10 回の処理を行う場合
for _ in progress_bar(range(10), total=10):
    time.sleep(0.5)  # 実際の処理が行われる部分
実行結果

こんなかんじで進捗バーっぽいのがでる。

[========================      ] 80.0%
やってること
import time
import sys

time モジュールと sys モジュールをインポート。
time モジュールは時間の管理(重たい処理代わりのスリープ)に使用され、sys モジュールは標準入出力(今回はstdout)を操作するために使用している。


def progress_bar(iterable, total=None, length=30):
    total = total or len(iterable)
    progress = 0

progress_bar 関数を定義。この関数はジェネレーターとして振る舞う。
引数として iterabletotal、および length を取るようになっており、total は処理の総数で、指定されていない場合は iterable の長さが使われる。length は進捗バーの長さを指定する。


    for item in iterable:
        yield item
        progress += 1

ジェネレーターなので、for ループで iterable の各要素を返し、同時に progress をインクリメントしている。yield はジェネレーター内で値を生成するためのキーワード。


        percent = progress / total
        fill_length = int(length * percent)

進捗のパーセンテージを計算し、進捗バーを表示するための長さを計算する。


        bar = f"[{'=' * fill_length}{' ' * (length - fill_length)}] {percent:.1%}"

bar 変数に進捗バーの文字列を構築。進捗バーは [==== ] 30.0% のような形式で表示する。


        sys.stdout.write('\r' + bar)
        sys.stdout.flush()

sys.stdout.write('\r' + bar) は、カーソルを行頭に戻して進捗バーを上書きする。
そして、sys.stdout.flush() は標準出力を即座にフラッシュして表示を更新する役割。

最後に、for ループの外に出ると、関数はジェネレーターとして振る舞うため、この関数を呼び出すときにはfor ループ内の処理が実行される。このときに進捗バーも更新される。

tqdmモジュールを使う場合

tqdmはPythonで進捗バーを表示するためのモジュールで、使いやすく進捗表示を提供してくれる。

モジュールのインストール
pip install tqdm
コード
from tqdm import tqdm
import time

# rangeの代わりにtqdmを使って進捗バーを表示
for i in tqdm(range(10), desc="Processing", unit="item"):
    time.sleep(0.5)  # 実際の処理が行われる部分
実行結果

こんな感じででる。かっこいい。

Processing:  40%|█████████████████████████▏                                     | 4/10 [00:02<00:03,  2.00item/s]

このコードでは、tqdmを用いてrange(10)の各要素に対するループを行っている。
descは進捗バーのラベルを、unitは進捗バーの単位を設定する。
tqdmは進捗バーをターミナル上に表示し、進捗が進むにつれてバーが更新されていく。
自前で作るよりtqdmが使っていいならこっちの方が見た目がかっこいいし楽。

タイトルとURLをコピーしました