引数をとるPythonアプリケーションを作りたい
例えば、以下のように動作するarg.pyを作りたい。
$ python3.6 arg.py --name Spam --count 4
Spam
Spam
Spam
Spam
$ python3.6 arg.py --count 4
Invalid argument
$ python3.6 arg.py
Invalid argument
以下の2つの方法を紹介します。
- Python nativeな方法(sys.argv)
- Clickを使う方法 ←こっちが本題
Python nativeな方法(読み飛ばしてOK)
起動時のコマンド名、引数はsys.argv
という配列に格納されています。
その内容を自力でパースしていく方法です。
# cli_sysargv.py
import sys
def get_arg(option_name):
for i, arg in enumerate(sys.argv[:-1]):
if arg == f"--{option_name}":
return sys.argv[i + 1]
return None
def say_hello():
try:
count = int(get_arg("count"))
name = get_arg("name")
except TypeError:
print("Invalid argument")
exit()
if not count or not name:
print("Invalid argument")
exit()
for i in range(count):
print(name)
if __name__ == "__main__":
say_hello()
今回のように引数が少ないときはまだやれますが、型の変換が必要だったり、入れ子のコマンド等になってくると、ややこしいですね。
また、エラーメッセージがざっくりとしてしまっています。
Clickを使う方法
PythonモジュールのClickを使う方法を紹介します。
以下、Githubページの概要の翻訳です。
Click(Command Line Interface Creation Kit)は、最低限のコードで美しいコマンドラインインターフェースをつくるためのPythonパッケージです。
幅広い設定が可能ですが、そのままでも、気の利いた動作をします。
Clickは、コマンドラインツールをコーディングするのを手軽に楽しくすることをねらって作られています。CLIを実装する技術に乏しくても、イライラすることなく、意図通りのCLIを実装できます。
以下がClickの主な魅了のようです。
– コマンドを好きにネストできる
– 自動でhelpを生成できる
– 実行時のサブコマンドのlazy loadingができる
インストールは以下のとおり。
$ sudo pip install click
コードを見てみましょう。非常に直感的でわかりやすく、とくに補足すべき点も見当たりません。
# cli_click.py
import click
@click.command()
@click.option('--count', required=True, type=int)
@click.option('--name', required=True, type=str)
def say_hello(count, name):
for i in range(count):
print(name)
if __name__ == "__main__":
say_hello()
また、$ python3.6 cli_click.py --help
と入力すると、
Usage: cli_click.py [OPTIONS]
Options:
--count INTEGER [required]
--name TEXT [required]
--help Show this message and exit.
このようなヘルプページまで出力してくれます。
他にも、未指定の場合プロンプトからの入力を求めたり、あらかじめ入力できる内容を絞ったりもできます。
詳細はこちらのClick Documentを参照してください。