LoginSignup
5
2

More than 1 year has passed since last update.

[python] click.progressbarの出力を消すオプション

Last updated at Posted at 2017-09-05

Pythonでコンソールアプリを使う際、clickのprogressbarを使うと、長時間の作業時に進捗がいい感じに可視化されてうれしいです。

しかし、場合によってはサーバープロセスやバッチ処理に, progressbarを当初使っていた処理の関数を入れたりする場合、オプション引数でprogressbarの出力をon/offしたい、というのがあると思います。

そんなとき使えるコードパターンをご紹介します。 => fileに/dev/nullを指定するテクニックを発見したのでそちらを最初に...

UNIX系で使えるシンプルなやりかた

import sys
import click


def something(items, show_progress=False):
    out = sys.stdout if show_progress else open('/dev/null', 'wb')
    with click.progressbar(items, file=out) as bar:
        for item in bar:
            'abcd' * (1024 * 10)


items = list(xrange(10000))
something(items, show_progress=True)
print('--------')
something(items, show_progress=False)

fileというオプションでclick.progressbarの出力先を指定できるようなので、/dev/nullへ書き込むファイルオブジェクトを指定すると、なにもでてこなくなります。
ただしこのsomethingのような関数を何千回も呼び出す場合はきちんとopenしたファイルオブジェクトをcloseした方がよいと思います。

/dev/nullがない環境でも使えるPythonのテクニックで解決するやり方

import functools
from contextlib import contextmanager
import click


@contextmanager
def dummy_bar(items, **kwargs):
    yield items


def something(items, show_progress=False):
    f = click.progressbar if show_progress else dummy_bar
    fbar = functools.partial(f, items, show_pos=True, show_eta=True)

    with fbar() as bar:
        for item in bar:
            'abcd' * (1024 * 10)


items = list(xrange(10000))
something(items, show_progress=True)
print('--------')
something(items, show_progress=False)

解説

なにも出力しないbarを作るものとして、dummy_barという関数を定義しました。
click.progressbarwith句で呼び出されるため、contextmanagerを使ってasのあとの変数に代入されるもの, すわなち引数で与えられたiterableをyieldでそのまま返しています。

使う関数をshow_progressオプションで切り替え、統一的に引数なしで呼び出せるようにfunctools.partialで引数を部分適用しています。
ですので本来with click.progressbar(...となっていたところではシンプルにwith fbar()となっています。

これでオプションの挙動に応じたbarasによって代入され、あとは普通にclick.progressbarのように使えばokです。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2