コマンドライン引数のパース
Pythonスクリプトでは今回のように引数を伴う処理が多々あります。ここまでで登場したサンプルで使用したsysモジュールのargvでもいいのですが、引数の数を検証したりする必要があります。
例えば、前回までに作成したコードは引数を省略して実行するとIndexErrorが発生してしまいます。
python main.py # IndexError: list index out of range
ユーザーには何が不足しているのかといった情報やヘルプ等を表示してあげたいところです。標準ライブラリのargparseを使用すると、help、デフォルト値の設定、型の指定といったことが簡単に実装できるため、今回はこちらを使用してみましょう。
argparseの簡単な使い方
まず、簡単な使い方について解説します。以下のようなオプションを指定する引数を定義する場合について考えてみます。
python main.py arg1 arg2 --opt1=val1 --opt2=val2
arg1、arg2は順番が決められていて必須、opt1、opt2は任意とします。以下のスクリプトで、上のようなコマンドを定義することができます。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("arg1")
parser.add_argument("arg2")
parser.add_argument("--opt1")
parser.add_argument("--opt2")
args = parser.parse_args()
print(args.arg1)
print(args.arg2)
print(args.opt1)
print(args.opt2)
実装のフローとしては、ArgumentParserを生成し、add_argumentで引数を追加していくことになります。上のコードではパラメータを指定して実行するとパラメータの値がprint出力されることが確認できます。また、パラメータの指定ない場合は以下のようなusageが表示されます。
usage: optsample.py [-h] [--opt1 OPT1] [--opt2 OPT2] arg1 arg2 optsample.py: error: the following arguments are required: arg1, arg2
また、helpも自動で実装されます。-hを指定して実行すると、以下のような出力を得ることができます。
usage: main.py [-h] [--opt1 OPT1] [--opt2 OPT2] arg1 arg2 positional arguments: arg1 arg2 optional arguments: -h, --help show this help message and exit --opt1 OPT1 --opt2 OPT2
ヘルプの設定
ArgumentParser()でdescriptionを、add_argumentでhelpを指定するとスクリプトと引数のhelpを追加することができます。先ほどのスクリプトを以下のように修正してみてください。
parser = argparse.ArgumentParser(description="サンプルスクリプトです。")
parser.add_argument("arg1", help="hogeを指定してください。")
parser.add_argument("arg2", help="fooを指定してください。")
parser.add_argument("--opt1", help="fugaを指定してください。任意です。")
parser.add_argument("--opt2", help="hugaを指定してください。任意です。")
-hオプションをつけて実行すると、以下のように出力されます。
usage: main.py [-h] [--opt1 OPT1] [--opt2 OPT2] arg1 arg2 サンプルスクリプトです。 positional arguments: arg1 hogeを指定してください。 arg2 fooを指定してください。 optional arguments: -h, --help show this help message and exit --opt1 OPT1 fugaを指定してください。任意です。 --opt2 OPT2 hugaを指定してください。任意です。
デフォルト値の設定
add_argumentの引数にdefaultでデフォルト値を指定することができます。この記述がない場合、Noneが設定されます。
parser.add_argument("--opt1", default=10, help="fugaを指定してください。")
これ以外にも様々なオプションを指定することが可能です。以下に細かく解説しているため、合わせて参考にしてください。
https://www.python.ambitious-engineer.com/archives/3023
実装例
以下は課題のメイン処理をArgumentParserを使用したものに書き換えた実装例です。
from settings import THRESHOLD
from argparse import ArgumentParser
from input_data import file2list
from aggregate import aggregate
from output_data import output_result
# コマンドライン引数設定
parser = ArgumentParser()
parser.add_argument("input_file_path", help="データファイルのパスを指定してください。")
args = parser.parse_args()
def main():
""" メイン処理 """
print("処理を開始します。")
# 入力データ検証・取得
data_list = file2list(args.input_file_path)
# 集計処理
result_count = aggregate(data_list, THRESHOLD)
# 出力処理
output_result(result_count)
if __name__ == '__main__':
main()
