argparse コマンドライン引数をパースする(オプションパーサ)

ページではargparseモジュールを使用してコマンドライン引数のオプションをパース方法について解説します。

コマンドライン引数のパース

Pythonでコマンドライン引数をパースする場合、よく見かける方法としては以下の3つが挙げられます。

  • sysモジュールのargvを使用する
  • argparseモジュールのArgumentParserを使用する
  • サードパーティ製のdocoptを使用する

簡単なスクリプトであればsys.argvでも良いのですが、ある程度機能が増えてくると任意オプションなどが必要となるため対応が難しくなります。argparseモジュールは標準ライブラリで用意されているオプションパーサで、オプションやhelp、デフォルト値の設定、型の指定といったことが簡単にできます。また、ここでは解説しませんが、docoptを使用するとdocstringに定義することも可能です。

argparseの簡単な使い方

まず、簡単な使い方について解説します(といってもほとんどの場合はこの使用方法で事足りると思います。)。以下のような引数を定義する場合について考えてみます。

python sample.py arg1 arg2 --opt1=val1 --opt2=val2

arg1、arg2は順番が決められていて必須、opt1、opt2は任意とします。以下のスクリプトで、上のようなコマンドを定義することができます。

# sample.py
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: optsample.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

help文の定義

それではここから様々なオプションを指定して上のスクリプトに少しづつ肉付けする方法について解説します。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: optsample.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を指定してください。任意です。

短縮オプション

いくつかのUnixコマンドは、--オプション以外に-オプションという形式の短縮したオプションが用意されています。--helpと-hみたいなものですね。add_argumentの第1引数に短縮を、第2引数にverboseをそれぞれに指定します。例えば、-oを--opt1の短縮としたい場合、以下のように追記します。

parser.add_argument("-o", "--opt1", help="fugaを指定してください。任意です。")

requiredによるオプションの必須化

オプション引数でも必須にしたい場合、add_argumentにrequired=Trueを指定します。例えば、先程のスクリプトのopt1を必須にしたい場合、以下のように記述します。

parser.add_argument("--opt1", required=True, help="fugaを指定してください。このオプションは必須です。")

なお、位置引数を非必須化することはできません。

defaultによるデフォルト値の設定

add_argumentの引数にdefaultでデフォルト値を指定することができます。この記述がない場合、Noneが設定されます。

parser.add_argument("--opt1", default=10, help="fugaを指定してください。")

typeによる型の設定

add_argumentの引数にtypeで文字列から変換する型を指定することができます。例えば、arg1にintを、art2にstrを指定させたい場合、以下のように記述します。

parser.add_argument('arg1', type=int, help="hogeを指定してください。")
parser.add_argument('arg2', type=str, help="fooを指定してください。")

不正な型を指定すると以下のようなエラー原因が表示されます。

optsample.py: error: argument arg1: invalid int value: 'a'

その他のオプション

add_argumentの引数で大抵の設定ができますが、さらに高度な使い方について解説します。

action

オプション引数に対して何を「値」とするかをadd_argumentの引数でactionで設定することができます。通常、オプション引数は--opt=値の形式で指定しますが、オプションの指定があれば無関係で何らかの値を使いたい、という場合があります。例えばバージョン番号を表す--versionなどが挙げられます。

actionを指定するとこういった制御が可能となります。actionには以下を指定することができます。

  • store_const:オプションが指定されている場合、constで指定した値を設定する
  • store_true:オプションが指定されている場合、Trueを設定する
  • store_false:オプションが指定されている場合、Falseを設定する
  • version:オプションが指定されている場合、versionで指定した値を設定する

例えば、以下のようなコードを実行した場合、

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--opt1', action='store_const', const=100)
parser.add_argument('--opt2', action='store_true')
parser.add_argument('--opt3', action='store_false')
args = parser.parse_args()
print(args.opt1)
print(args.opt2)
print(args.opt3)

実行結果は以下のようになります。

$ python sample.py --opt1 --opt2 --opt3
100
True
False

また、例えば--versionでバージョンを設定したい場合、以下のようになります。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--version', action='version', version='1.01')
args = parser.parse_args()
print(args.version)

nargs

さきほどはオプションに対して値なしの場合についてactionを使用しましたが、nargsを使用すると複数の値を設定することができるようになります。opt1に対して3つの値を設定する場合、以下のように記述します。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--opt1', nargs=3)
args = parser.parse_args()
print(args.opt1)

実行すると、オプションに指定した複数の値がlistで格納されていることが確認できます。

$ python optsample.py --opt1 a b c
['a', 'b', 'c']

typeで初期化処理

typeは型を指定できますが、関数オブジェクトを指定して初期化処理を行うことも可能です。例えば、--langsにカンマ区切りで複数の値を指定したい場合、以下のように初期化処理をtypeに指定することができます。

import argparse

def init(lang):
    return lang.split(",")

parser = argparse.ArgumentParser()
parser.add_argument('--langs', type=init)
args = parser.parse_args()
print(args.langs)

実行すると以下のような出力を得ることができます。

$ python optsample.py --langs=ja,en,tw
['ja', 'en', 'tw']