コマンドライン引数は、コマンドライン上からプログラムを実行する際に設定する引数です。
リストsys.argvを直接読み込む方法もありますがargparseモジュールを使うと、
- 位置引数・オプション引数の設定
- helpメッセージの生成
- 排他グループの設定
等の高度な処理を実現することができます。本記事では、これらについて具体例を挙げながらまとめました。
確認した環境
- OS: Ubuntu 16.04LTS
- Python3.7.3@Anaconda
基本的な使い方
手順を以下に示します。
(1)ArgumentParserオブジェクトの生成する
argparse.ArgumentParser()により、ArgumentParserオブジェクトを生成します。
# argparseモジュールをインポート
>>> import argparse
# ArgumentParserオブジェクトを生成
>>> parser = argparse.ArgumentParser()
(2)コマンドライン引数を追加する
add_argument()メソッドを使ってコマンドライン引数を定義します。(詳細は後述)
ここで定義されたン引数は保存され、次項に示すparse_arg()が呼び出された時に利用されます。
# コマンドライン引数の設定(位置引数x,yをint型で設定)
>>> parser.add_argument("x", help="a number x", type = int)
>>> parser.add_argument("y", help="a number y", type = int)
# コマンドライン引数の設定(オプション引数modeをint型で[0, 1, 2]から選択)
>>> parser.add_argument("-m", "--mode", help="define mode", type = int, choices=[0,1,2], default = 0)
(3)コマンドライン引数を利用する
parse_args()メソッドを使ってsys.argvからコマンドライン引数を取得し、内容を解析してプログラム中で使えるようにします。
# sys.argvからコマンドライン引数を取得し、解析します
>>> args = parser.parse_args()
# 上記で定義したオプション引数"mode"の値をargs.modeに格納
# 以降では、modeの値によって処理を分ける例を記載
# mode = 2 の時はx+yを表示
>>> if args.mode >= 2:
>>> z = args.x + args.y
>>> print("Adding: {} + {} = {}".format(args.x, args.y, z))
# mode = 1 の時はx*yを表示
>>> elif args.mode >= 1:
>>> z = args.x * args.y
>>> print("Multipling: {} * {} = {}".format(args.x, args.y, z))
# mode = 0 の時はx、yそれぞれを表示
>>> else:
>>> print("x = {}, y = {}".format(args.x, args.y))
上記例で示したコードをファイル名”prog.py”に保存し、実行した結果を以下に示します。
$ python3 prog.py 2 3 --mode 2
Adding: 2 + 3 = 5
$ python3 prog.py 2 3 --mode 1
Multipling: 2 * 3 = 6
$ python3 prog.py 2 3 --mode 0
x = 2, y = 3
#choiceパラメータに無い値を設定するとエラーメッセージがでます。
$ python3 prog.py 2 3 --mode 3
usage: prog.py [-h] [-m {0,1,2}] x y
prog.py: error: argument -m/--mode: invalid choice: 3 (choose from 0, 1, 2)
$ python3 prog.py 2 3
x = 2, y = 3
コマンドライン引数の定義
コマンドライン引数を設定するには、add_argument()メソッドを使います。
使い方は以下です。
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
引数がたくさんあるので、ここでは使いそうなものをいくつか記載します。
引数 | 説明 |
---|---|
name or flags | 位置指定引数(x、yなど)、or オプション引数(-m、--modeなど)を設定 |
action | コマンドライン引数がどう処理されるかを設定。 例えば'action = store_ture'や'store_false'と設定すると、それぞれの初期値がTrue、Falseに設定される。 |
help | コマンドライン引数の説明文 |
type | コマンドライン引数はデフォルトでstr型で読み込まれるが、int型やfloat型など他の型で読み込む場合に使用 |
choice | コマンドライン引数の値を限られた選択肢から選びたい時に使う。引数の値が選択肢に存在しない場合はエラーメッセージを返します。 このオブジェクトの型はtypeパラメータで指定したものと同じにすることに注意が必要 |
default | オプション引数が省略された場合、それらの引数がとる値を設定 |
例をいくつか示します。
# 位置引数x,yをint型で設定
>>> parser.add_argument("x", help="a number x", type = int)
>>> parser.add_argument("y", help="a number y", type = int)
# オプション引数modeをint型で[0, 1, 2]から選択
>>> parser.add_argument("-m", "--mode", help="define mode", type = int, choices=[0,1,2], default = 0)
排他グループの設定
排他(どっちか選ぶ)のコマンドライン引数を設定する場合の手順を以下に示します。
- add_mutually_exclusive_group()メソッドを使って、相互排他グループを作ります
- 相互排他とするコマンドライン引数を、上記で設定したグループに登録します。
>>> import argparse
>>> parser = argparse.ArgumentParser()
# 相互排他グループの生成
>>> group = parser.add_mutually_exclusive_group()
以下は、コマンドライン引数”multi”と”add”を相互排他グループ”group”に登録した例です。
これでどちらか一方のみしか選択できなくなります。
# 上記で設定した相互排他グループに属する引数の設定
>>> group.add_argument("-m", "--multi", help="multiplying values", action='store_true')
>>> group.add_argument("-a", "--add", help="adding values", action='store_true')
一通りの流れをサンプルコード(prog02.py)を使って見ていきます。
import argparse
parser = argparse.ArgumentParser()
# コマンドライン引数の設定(位置引数を設定)
parser.add_argument("x", help="a number x", type = int)
parser.add_argument("y", help="a number y", type = int)
# 相互排他グループの生成
group = parser.add_mutually_exclusive_group()
# 上記で設定した相互排他グループに属する引数の設定
group.add_argument("-m", "--multi", help="multiplying values", action='store_true')
group.add_argument("-a", "--add", help="adding values", action='store_true')
# namespaceオブジェクトの生成
args = parser.parse_args()
#排他グループによる処理分岐
#--multiを設定した場合の処理
if args.multi:
z = args.x * args.y
print("Multipling: {} * {} = {}".format(args.x, args.y, z))
#--addを設定した場合の処理
elif args.add:
z = args.x + args.y
print("Adding: {} + {} = {}".format(args.x, args.y, z))
#排他グループの引数が設定されない場合の処理
else:
print("x = {}, y = {}".format(args.x, args.y))
実行結果を以下に示します。意図したとおりに動作しています!
$ python3 prog02.py 2 3 --multi
Multipling: 2 * 3 = 6
$ python3 prog02.py 2 3 --add
Adding: 2 + 3 = 5
#排他設定した引数を両方設定するとエラーが発生
$ python3 prog02.py 2 3 --add --multi
usage: prog02.py [-h] [-m | -a] x y
prog02.py: error: argument -m/--multi: not allowed with argument -a/--add
$ python3 prog02.py 2 3
x = 2, y = 3
まとめ
argparseモジュールを使ったコマンドライン引数の設定方法についてまとめました。sys.argv変数を使った場合よりも高度な設定が可能となります。