Help us understand the problem. What is going on with this article?

clizeでCLIを楽々作成

More than 1 year has passed since last update.

こないだ、clizeというpythonライブラリを見つけました。
なかなかいいライブラリだったので、紹介します。

このclizeですが、何をしてくれるのかというと、CLIの簡単作成です。
「いやいや、fireで間に合ってますけど。」って思った方もいると思います。

今回は、pythonでCLIを作る際によく使うライブラリを比較しつつ、clizeについて紹介できればと思います。

python CLIライブラリ比較

python CLIライブラリは、clizeを含めて下の3つを押さえておけばいいのかなと勝手に思っています。

  1. argparse
  2. fire
  3. clize

この3つを、簡単な算数のスクリプトを作成するサンプルで比較していきます。

1. argparse

argparseは、pythonの標準ライブラリです。
標準ライブラリと考えるとよくできていますが、コード量が多く、「ん?これなんだっけ?」となりがちです。

コードはこんな感じになります。

argparse-sample.py
def main(a: int, b: int, c: float=0.5):
    """
    a × b × c を実行し、結果を返す。

    :param a: 整数を入力してください。
    :param b: 整数を入力してください。
    :param c: 浮動小数点数を入力してください。何も入力しなければ、自動的に0.5が選択されます。
    :return: a × b × c
    """
    return a * b * c

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument("a", type=int,
                        help="整数aを入力してください。")
    parser.add_argument("b", type=int,
                        help="整数bを入力してください。")
    parser.add_argument("c", type=int, default=0.5,
                        help="浮動小数点数を入力してください。何も入力しなければ、自動的に0.5が選択されます。")

    args = parser.parse_args()

    main(args.a, args.b, args.c)

定義も面倒ですし、値を取得する際にargs.aなどと書く必要があり、さらに面倒です。
main(a, b, c)の引数が仕様変更された場合などに、「えーっと、なんだっけ?」となりがちです。

helpはこんな感じ。

$ python argparse-sample.py --help

usage: sample.py [-h] a b c

positional arguments:
  a           整数aを入力してください。
  b           整数bを入力してください。
  c           浮動小数点数を入力してください。何も入力しなければ、自動的に0.5が選択されます。

optional arguments:
  -h, --help  show this help message and exit

2. fire

続いてのfireは、Google製のライブラリです。
これが一番使われているのかなと勝手に思っています。

argparseに比べて、「CLI生成を自動化しているぞ!」という気持ちになりやすいです。

fire-sample.py
def main(a: int, b: int, c: float=0.5):
    """
    a × b × c を実行し、結果を返す。

    :param a: 整数を入力してください。
    :param b: 整数を入力してください。
    :param c: 浮動小数点数を入力してください。何も入力しなければ、自動的に0.5が選択されます。
    :return: a × b × c
    """
    return a * b * c

if __name__ == '__main__':
    import fire
    fire.Fire(main)

fire.Fire(main)だけで、関数を丸ごとCLI化することができます。
また、クラスについても、class MyClass(fire.Fire)とするだけで、全メソッドをCLI化することができます。

ただ、不便な点もあります。

  • -- --helpという変なヘルプの出力方法。
  • 変数の説明を表示できない。多分。(知ってたら教えてください。。。)
  • 変数の型を勝手に変えてきて、時々うざい。

ヘルプはこんな感じ。

$ python fire-sample.py -- --help

Type:        function
String form: <function main at 0x108d67e18>
File:        ~/Repos/projects/kito-xgx-autotuning/bin/sample.py
Line:        38
Docstring:   a × b × c を実行し、結果を返す。

:param a: 整数を入力してください。
:param b: 整数を入力してください。
:param c: 浮動小数点数を入力してください。何も入力しなければ、自動的に0.5が選択されます。
:return: a × b × c

Usage:       sample.py A B [C]
             sample.py --a A --b B [--c C]

docstringが表示されるので、申し訳程度に説明を書くことはできますが。。。
また、型の自動変換についても、クセが強いです。
公式からのコピペですが、例えばこんな動き。

example.py
import fire
fire.Fire(lambda obj: type(obj).__name__)
$ python example.py 10
int
$ python example.py 10.0
float
$ python example.py hello
str
$ python example.py '(1,2)'
tuple
$ python example.py [1,2]
list
$ python example.py True
bool
$ python example.py {name: David}
dict
$ python example.py 10
int
$ python example.py "10"
int
$ python example.py '"10"'
str
$ python example.py "'10'"
str
$ python example.py \"10\"
str

役立つこともあるんですが、たまにうざい。
古いバージョンでは四則演算機能までついていたので、日付を2019-10-25のように書くと、引き算されて1984になってしまったこともありました。

3. clize

そして、本題のclize。clizeのいいところは、下の通り。

  • fireとほぼ同じ感覚でCLI自動作成をできる。
  • --help-hでヘルプが出る。
  • docstringをパースし、ヘルプに表示してくれる。
  • type annotationを見て、型を変換してくれる。

もちろん、ダメなところもあります。

  • --a 10-a 10のような書き方ができず、常に10 20 abcのような書き方しかできない。

結構致命的ですね。--a 10-a 10のフォーマットに対応してくれたら最高なのに。追加してPR出そうかな。。。

コードはこんな感じ。

clize-sample.py
def main(a: int, b: int, c: float=0.5):
    """
    a × b × c を実行し、結果を返す。

    :param a: 整数を入力してください。
    :param b: 整数を入力してください。
    :param c: 浮動小数点数を入力してください。何も入力しなければ、自動的に0.5が選択されます。
    :param d: 文字列を入力してください。何も入力しなければ、自動的にabcが選択されます。
    :return: a × b × c
    """
    return a * b * c


if __name__ == '__main__':
    from clize import run
    run(main)

ヘルプはというと、

$ python clize-sample.py --help
Usage: bin/sample.py a b [c]

a × b × c を実行し、結果を返す。

Arguments:
  a            整数を入力してください。 (type: INT)
  b            整数を入力してください。 (type: INT)
  c            浮動小数点数を入力してください。何も入力しなければ、自動的に0.5が選択されます。 (type: FLOAT, default: 0.5)

Other actions:
  -h, --help   Show the help

docstringをパースし、typeや説明を表示してくれています。
このhelp画面が最高です。

まとめ

最後に3ライブラリの特徴をまとめると、

  1. argparse: 公式ライブラリ。コード量が多い。
  2. fire: 簡単。ただし、ヘルプや型などクセが強い。
  3. clize: 簡単。docstringやtype annotationを使ってくれる。ただし、--aのような書き方ができない。

いかがでしたか?あれ、「案外clizeいいやつじゃん」と思っていただけた方がいれば幸いです。
「clizeに-aつけるぞ!」って方がいれば、ぜひ頑張って欲しいです。

以上、clizeの紹介でした。これ誰が読むんやろ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした