4

次のように使用することを目的として、実行時間の長いコンソールプロセスの進行状況インジケーターを作成しています。

pi = ProgressIndicator()
for x in somelongstuff:
    do stuff
    pi.update()
pi.print_totals()

基本的には、ドットとダッシュが付いたある種のプログレスバーを出力し、最後に「234234バイト処理済み」のようなものを出力する必要があります。

コンテキストマネージャーとして使用するとよいと思いました。

with ProgressIndicator() as pi:
    for x in somelongstuff:
       do stuff
       pi.update()

ただし、このソリューションについて私が懸念していることがいくつかあります。

  • 余分なインデントにより、インジケーター機能が実際よりも重要に見えるようになります
  • ProgressIndicatorループで発生する可能性のある例外を処理したくない

これはコンテキストマネージャーの有効なユースケースですか?他にどのような解決策を提案できますか?

4

2 に答える 2

3

それは間違いなく有効なユースケースのようです。コンテキスト マネージャーは、必要がない場合は例外を処理する必要はありませんが、プログレス バーが出力される行を終了して、トレースバックと混同されないようにし、合計を出力しないようにする必要があります。例外によって終了した場合。

インデントに関しては、ユーザーが進行状況を確認できるようにすることは、実際には非常に重要な機能であるため、インデント レベルを使用しても問題ないと主張したいと思います。

于 2012-07-04T11:06:04.060 に答える
2

非常によく似た API を持つ GUI アプリケーションがあり、次のProgressTaskように使用します。

def slow_func():
    t = nuke.ProgressTask()
    t.setMessage("Doing something")
    for x in range(100):
        do_something()
        t.setProgress(x+1)

ProgressTask.__del__呼び出されると、進行状況バーの UI が消えます。これはほとんどの場合うまく機能しますが、(たとえば によってdo_something()) 例外が発生した場合、トレースバック オブジェクトはProgressTaskオブジェクトへの参照を保持するため、プログレス バーはスタックします (別のトレースバックが発生するまで)。

ProgressTaskcontext-manager プロトコルが実装されているため、このメソッドを使用して__exit__進行状況バーが非表示になっていることを確認できます。

コマンドラインUI(あなたが書いているように聞こえます)の場合、これは問題にならないかもしれませんが、######### 100% (error)タイプバーを表示したり、トレースバック出力が混乱しないようにするなど、同様のクリーンアップタスクを実行できます。

プログレスバー クラスが両方の方法で使用できない理由はありません。ほとんどのコンテキスト マネージャーは、通常のオブジェクトとコンテキスト マネージャーの両方として完全に使用できます。

lock = threading.Lock()
lock.acquire()
lock.release()
# or:
with lock:
    pass
于 2012-07-04T11:11:39.257 に答える