Python コマンドライン引数ライブラリ¶
Python標準ライブラリには、argvライブラリとargparseライブラリの2種類が提供されています。
argvライブラリ¶
非常にシンプルなライブラリで、Pythonを実行したコマンドラインの引数文字列をリストで取得します。sys.argv
でコマンドライン記述が配列に格納されます。argv[0]
はスクリプトのファイル名、argv[1]
以降にコマンドライン引数が格納されます。
引数の数は、len(argv)
で取得できます(実行プログラムがargv[0]
に入るので、引数がある場合は2以上になります)。
argparseライブラリ¶
必須引数、オプション引数、引数の型変換、ヘルプ表示などかなり高機能なライブラリです。
argparseライブラリの最初の一歩¶
コマンドライン引数のパーサーを作成し、このパーサーに引数を解析させて引数を取得します。ここで引数の指定は次とします。
コマンド <input名> [--line NN]
- input名は必須の引数
- --line NNは指定してもしなくても良い引数
import argparse # ①argparseライブラリのインポート
:
parser = argparse.ArgumentParser() # ②コマンドライン引数パーサーの作成
parser.add_argument('input') # ③必須引数をパーサーに定義
parser.add_argument('-l', '--line') # ④オプション引数をパーサーに定義
:
args = parser.parse_args() # ⑤コマンドライン引数の解析を実施
print(f'{args.input=}') # ⑥必須引数(③で定義)を参照
print(f'{args.line=}') # ⑦オプション引数(④で定義)を参照
- 引数の定義で、ハイフンで始まらない名前の定義は必須の引数となり、定義順に1つ目、2つ目の引数となります。オプション引数は必須引数の前でも後でも指定が可能です。そこで、上述の定義では、次の順番での指定が可能です。
work$ ./arg_sample.py input.txt
work$ ./arg_sample.py input.txt --line 33
work$ ./arg_sample.py --line 33 input.txt
- オプション引数は、一つのハイフンで1文字のオプション名(省略名)、2つのハイフンでフルオプション名と使い分けることが可能です。
-l 33
と指定することも、--line 33
と指定することも可能です。
- 必須引数が指定されていないと、エラーとなりコマンドライン書式のメッセージを出力してプログラムが終了します。
work$ ./arg_sample.py usage: arg_sample.py [-h] [-l LINE] input arg_sample.py: error: the following arguments are required: input
- コマンドライン引数を解析し、結果を argparse.Namespace型のオブジェクトで返却します。このオブジェクトに引数名で参照すると引数の内容を取得できます。
args.input
で、引数名inputの値を取得args.line
で、引数名lineの値を取得(引数名は、2連続ハイフンで指定した正式名となります)
- ヘルプオプション
-h
が自動で生成され、コマンドライン書式のメッセージを出力します。work$ ./arg_sample_1.py -h usage: arg_sample_1.py [-h] [-l LINE] input positional arguments: input options: -h, --help show this help message and exit -l LINE, --line LINE
引数の定義色々¶
必須引数を任意個数指定¶
引数定義に、 nargs で個数を指定します。'*'は0個以上、'+'は1個以上、'3'は3個parser.add_argument('input', nargs='+')
解析結果はリストで返却されます。
必須引数が2つ以上あり、後続に必須引数がある引数で任意個数指定をすることは可能です。後続の必須引数を満たす分を除き残りの引数を取得します。
parser = argparse.ArgumentParser()
parser.add_argument('input', nargs='+')
parser.add_argument('output')
この定義では、必須引数を2つ指定しています。ここで、引数に、alfa bravo charlie
と指定すると、['alfa', 'bravo']がinput引数の値に、'charlie'がoutput引数の値になります。
オプション引数を任意個指定¶
parser.add_argument('-l', '--lines', nargs='+')
この定義では、--lines 11 13 17
と複数のオプション引数の値を指定できます。
オプション引数の繰り返し指定¶
同じオプション引数を複数回指定し、それらをリストとして取得することができます。
parser.add_argument('-l', '--lines', action='append')
この定義では、--line 11 --line 13
と複数回オプション引数を指定すると、[11, 13]のリストが取得できます。
actionにappendを指定しないと、最後に指定したオプションが1つ取得できます。
複数のパーサーを定義する¶
gitでは、サブコマンドによって引数の定義が変わります。例)git status, git pull, ... のように、gitコマンドのサブコマンド status, pull によってコマンドライン引数の指定を変えたい場合などで必要な機能です。
この時は、subparsersを使います。
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers() # サブパーサーの作成
parser_delta = subparsers.add_parser('delta') # サブコマンド delta のパーサーを生成
parser_delta.add_argument('input') # サブコマンド delta の必須コマンドライン引数
parser_delta.add_argument('-d', '--deltavalue') # サブコマンド delta のオプション引数
parser_echo = subparsers.add_parser('echo') # サブコマンド echo のパーサーを生成
parser_echo.add_argument('input') # サブコマンド echo の必須コマンドライン引数
args = parser.parse_args() # コマンドライン解析実施
work$ arg_sample.py delta input.txt -d 20
work$ arg_sample.py echo input2.txt
サブコマンドにより処理を振り分け(1)¶
上述では、サブコマンドが何であったかを拾って処理を振り分けるのが難しいので、サブコマンド名を args から拾えるようにします。
subparsers = parser.add_subparsers(dest='subcommand', required=True) # サブパーサーの作成時にdest属性指定
:
if args.subcommand == 'delta':
# ...
elif args.subcommand == 'echo':
# ...
- サブパーサーの作成時に、dest属性を指定しておくと、サブコマンドで何が指定されたかを取得できます。
サブコマンドにより処理を振り分け(2)¶
もう一つの方法は、サブコマンドでパーサーが振り分けられたときに指定した関数を実行するよう設定しておきます。
import argparse
def delta(args):
print(args)
def echo(args):
print(args)
def main():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subcommand', required=True)
parser_delta = subparsers.add_parser('delta')
parser_delta.add_argument('-d', '--deltavalue')
parser_delta.set_defaults(func=delta)
parser_echo = subparsers.add_parser('echo')
parser_echo.add_argument('message')
parser_echo.set_defaults(func=echo)
args = parser.parse_args()
args.func(args)
- サブパーサーのデフォルト関数に、実行したい関数を設定します。コマンドラインのパース後にfuncを実行すると、この設定した関数が呼ばれます。