https://www.komee.org/entry/2018/10/27/120000www.komee.org
前回のこの記事を書いたときに、コマンドライン引数を処理するために使ったargparseがめっちゃ便利で感動したので記事にした。
コマンドライン引数の処理
sample.py
というスクリプトを実行する時、一般に次のように実行する。
$ python sample.py
次に、sample.pyに-a
オプションや-b
オプションが使えるとしたら次のようになると思う。
$ sample.py -a hoge -b gege
一般的にこういう実装をしようとしたときは、sys.argvを受け取ってsplitして条件分けしてある引数が存在したらそれに対応する操作をして、、、みたいな感じになると思われる。
簡単に言うと、実装がめんどくさい
(私の実装力が低いだけというのもあるが)
こんな時に、pythonであれば、標準実装のargparse
というライブラリをインポートすると、さくっと実装できてしまうのである!
まずはargparseの説明をする。
argparseとは
argparseモジュールは、ユーザフレンドリなコマンドラインインタフェースの作成を簡単にします。プログラムがどんな引数を必要としているのかを定義すると、argparseがsys.argvからそのオプションを解析する方法を見つけ出します。argparseモジュールは自動的にヘルプと使用方法メッセージを生成し、ユーザが不正な引数をプログラムに指定したときにエラーを発生させます。 https://docs.python.jp/3/library/argparse.。html
簡単に言うと、コマンドライン引数の処理を簡単に実装できるライブラリである。
特筆すべきは、実装と同時にヘルプページと使用方法のメッセージも勝手に作成してくれるということである!
先に実装した前回の記事を例に説明すると、-h
引数をスクリプトに渡したときの処理を勝手に作ってくれるのである。
$ python unimove.py -h usage: unimove.py [-h] [-f FRAME] [-s START] input positional arguments: input Absolute/relative path to input file optional arguments: -h, --help show this help message and exit -f FRAME, --frame FRAME Number of interval frame -s START, --start START Time of union start
こんないい感じの使い方とヘルプページは、私は一切実装していない。
使い方
では具体的な実装方法を説明する。
私の以前実装したコードを例に、必要な箇所のみを抜粋して説明する。
必要なライブラリは、argparse
。今回は、from argparse import ArgumentParser
としてインポートした。
from argparse import ArgumentParser def get_option(): argparser = ArgumentParser() argparser.add_argument('input', type=str, help='Absolute/relative path to input file') argparser.add_argument('-f', '--frame', type=int, default=3, help='Number of interval frame') argparser.add_argument('-s', '--start', type=int, default=0, help='Time of union start') args = argparser.parse_args() return args if __name__ == '__main__': args = get_option() inputFile = args.input frame = args.frame startTime = args.start unimove(inputFile, frame, startTime)
オブジェクトの定義
argparser = ArgumentParser()
今回、引数処理をする関数はget_option()として定義し、この中ですべての引数処理を行うようにした。
get_option()の中では最初にまずArgumentParser()オブジェクトの定義をし、argparserとする。
引数の定義
argparser.add_argument('input', type=str, help='Absolute/relative path to input file') argparser.add_argument('-f', '--frame', type=int, default=3, help='Number of interval frame') argparser.add_argument('-s', '--start', type=int, default=0, help='Time of union start')
argparser.add_argument()で引数をargparserに追加していく。
この時、引数の名前に--をつけたものはオプション引数として定義され、省略ができるようになる。
よって今回の場合は、input
が自動的に必須の引数となり、それ以外の--frame
と--start
は省略可能となる。
また、後々に引数の値をプログラム内で呼び出す際には、基本的にはここで定義した名前が属性名となり使われる。このとき、--frame
として定義した名前は、属性名はframe
となる。
type
で指定した型で値をパースして保持し、省略された場合はdefault
にセットした値が使われるのはなんとなくわかるだろう。
また、helpに指定された部分は、このプログラムを-h
をつけて実行した場合に表示されるhelpページの引数の説明のところに表示される。
つまり、完成したプログラムを使用して、ヘルプを表示すると先程のヘルプが爆誕する。
他にもadd_argumentは様々なオプション引数があり、詳しくは公式リファレンスを参照するといい。
引数に定義された値の呼び出し
ここまでに定義されたオブジェクトは、argparser.parse_args()
として、mainに返す。
def get_option(): . . args = argparser.parse_args() return args
返されたargsの中に、引数情報が格納されており、これを先に定義した属性で呼び出すことで、プログラム内で用いることができる。
if __name__ == '__main__': args = get_option() inputFile = args.input frame = args.frame startTime = args.start unimove(inputFile, frame, startTime)
まとめ
やはり、特にhelpが勝手に生成されるのは非常に便利だなぁと思った。 加えて面倒な引数処理もいい感じにやってくれて、プログラムの中で使うに当たって非常に使いやすくなったと思う。今後のヘビロテが確定した。