Python のライブラリ argparse
をご紹介したいと思います。
import argparse
概要
argparse
は「 arg(ument) + parse 」という名前のとおり、コマンドライン引数を管理するためのライブラリです。
公式ページでは次のような説明がなされています。
The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.
意訳: argparse
モジュールを使うと、ユーザーフレンドリーなコマンドラインインタフェースがかんたんに作れます。プログラムがどのような引数を取るのかを定義しておけば、 argparse
はそれらを sys.argv
からパースする方法を理解してくれます。また、プログラムのヘルプや使い方のメッセージを生成したりユーザーが不正な引数を渡したときにエラーを出したりといったことも自動的に行ってくれます。
Python でコマンドライン引数といえば sys.argv
ですが、 sys.argv
はあくまでもコマンドライン引数をそのまま格納しただけのリストです。 argparse
は引数の取得だけでなく、引数の検証や制限、自動変換、フォールバック、ヘルプの生成など引数の取り扱いに関する一連の便利機能を提供してくれます。
私は単純に食わず嫌いで argparse
を使っていない時期が長いのですが、その使いやすさを知ったときは「もっと早く知れていれば!」と残念がりました。 Python 本体に同梱ですぐに使い始められるので、今は Python でちょっとしたコマンドラインツールを作るときにはほぼ毎回といってよいぐらい頻繁に利用しています。
インストール
インストール方法についてです。といっても、 argparse
は Python の 2.7 、 3.2 以降は標準ライブラリとして Python 本体に同梱されています。 pip
などで別途インストールする必要はありません。
使い方
基本的な使い方を見ていきましょう。
まずは最もシンプルなサンプルコードから。
argparse_sample_1.py
:
# coding: utf-8
import argparse
from pathlib import Path
"""ファイルのメタ情報を確認する
usage:
$ python argparse_sample_1.py sample.txt
"""
def main():
"""本スクリプトの main
"""
# 引数を取得する
args = get_args()
# 引数のうち file の部分を取得してそのメタ情報を出力する
path = Path(args.file)
print(path.lstat())
def get_args():
"""ファイル名をコマンドライン引数から取得する
"""
parser = argparse.ArgumentParser('Show file meta info.')
parser.add_argument('file', help='Target file.')
return parser.parse_args()
if __name__ == '__main__':
main()
argparse
とは別に利用されているもうひとつのライブラリ pathlib
はファイルシステムを扱うための標準ライブラリです。ここでの説明は割愛します。興味のある方は公式ページなどをご覧になってみてください。
肝心の argparse
についてです。上のコードの中で argparse
は関数 get_args()
の中で使われています。
parser = argparse.ArgumentParser('Show file meta info.')
コードを追いながら説明していきます。
まずは ArgumentParser()
で ArgumentParser
オブジェクトを生成しています。引数の 'Show file meta info.'
というのはプログラム名です。このプログラム名は省略することが可能で、省略するとスクリプト名になります(この場合は argparse_sample_1.py
)。
parser.add_argument('file', help='Target file.')
つづいて ArgumentParser
オブジェクトの add_argument()
メソッドでコマンドライン引数をひとつずつ定義しています。 add_argument()
の第 1 引数として渡されている 'file'
は引数名です。第 2 引数の help
はヘルプテキストです。こちらはコマンドのヘルプテキストにおいて引数の説明文となります。
return parser.parse_args()
最後に parse_args()
メソッドで実際に引数の取得処理( sys.argv
のパース)を行っています。
続く関数 main()
の中では parse_args()
の戻り値を利用しています。この戻り値は argparse.Namespace
というクラスのオブジェクトで、パースされた引数をプロパティとして格納しています。 add_argument('file', help='Target file.')
で定義された引数には同名のアトリビュート args.file
でアクセスできるようになっています。
ここまでで見たとおり、 argparse
の基本は次の 4 ステップになります。
ArgumentParser
オブジェクトの生成- 引数定義の追加
- 引数のパース
- 引数の利用
このスクリプトファイル argparse_sample_1.py
はコマンドラインから以下のような形で利用することができます。
引数なしで利用:
$ python argparse_sample_1.py
usage: Show file meta info. [-h] file
Show file meta info.: error: the following arguments are required: file
引数を渡して利用:
$ python argparse_sample_1.py sample.txt
os.stat_result(st_mode=33188, st_ino=54935441, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=559, st_atime=1493990821, st_mtime=1493990817, st_ctime=1493990817)
help
オプションをつけて利用:
$ python argparse_sample_1.py --help
usage: Show file meta info. [-h] file
positional arguments:
file Target file.
optional arguments:
-h, --help show this help message and exit
引数 file
が正しく渡されなかった場合は使用方法とエラーが表示され、その後の処理は行われません。引数が正しく渡されたときにだけ、その後の処理が実行されるようになります。
また、 --help
オプションが自動的にサポートされるようになりました。
argparse_sample_1.py
は引数を 1 つだけ取る最もシンプルな例でした。もう少し長い例を見てみましょう。
argparse_sample_2.py
:
# coding: utf-8
import argparse
def main():
"""引数をチェックする
"""
args = get_args()
print(args)
print(args.format)
print(args.encode)
print(args.verbose)
print(args.max_lines)
def get_args():
"""コマンドライン引数を取得する
"""
parser = argparse.ArgumentParser('diff csv files.')
parser.add_argument('-f', '--format', dest='format', default='csv', choices=('csv', 'tsv'), help='file format (default: csv).')
parser.add_argument('-e', '--encode', dest='encode', default='utf8', choices=('utf8', 'sjis'), help='file encoding.')
parser.add_argument('-v', '--verbose', action='store_true')
parser.add_argument('-m', '--max-lines', type=int, default=0)
parser.add_argument('files', nargs=2, type=argparse.FileType('r'), help='2 csv files.')
return parser.parse_args()
if __name__ == '__main__':
main()
こちらは私が以前作成した「 2 つの csv ファイルを比較するコマンドラインツール」から引数の部分のみを抽出したものです。
argparse_sample_1.py
よりも add_argument()
メソッドの行が増えたという違いはあるものの、次の 4 ステップは共通しています。
ArgumentParser
オブジェクトの生成- 引数定義の追加
- 引数のパース
- 引数の利用
add_argument()
の行を順番に見ていきましょう。
parser.add_argument('-f', '--format', dest='format', default='csv', choices=('csv', 'tsv'), help='file format (default: csv).')
この行では --format
というオプション引数を定義しています。
'-f'
と '--format'
はそのオプション引数の指定パターンを指定しています。 dest='format'
は parse_args()
の戻り値となる argparse.Namespace
オブジェクトにおいて当該引数を格納するプロパティ名を指定しています。ですので、こちらは args.format
で取得できることになります。 default='csv'
は --format
オプションが指定されなかった場合のデフォルト値を、 choices=('csv', 'tsv')
は受け付け可能なパターンを指定しています。ですので、これは「 --format
に指定できる値は 'csv'
と 'tsv'
のどちらかに絞りたくて、一切指定しなかった場合の値は 'csv'
にフォールバックしてほしい」という意味になります。
parser.add_argument('-e', '--encode', dest='encode', default='utf8', choices=('utf8', 'sjis'), help='file encoding.')
続くこの行では --encode
というオプション引数を定義しています。引数のパターンは --format
の場合と同じなので説明は不要でしょう。こちらで対象ファイル読み込み時の文字コード指定ができるようになりました。
parser.add_argument('-v', '--verbose', action='store_true')
こちらは --verbose
というオプション引数を定義しています。 action='store_true'
で、オプションが指定された場合は True
を、指定されなかった場合は False
がその値となります。 action
のパターンとしてはこの他に 'store' ```` 'store_const' ```` 'store_true' ```` 'store_false' ```` 'append'
などさまざまなものが用意されています。
parser.add_argument('-m', '--max-lines', type=int, default=0)
この行は --max-lines
というオプションを定義しています。 type=int
でそのオプションに渡せる値が int
型限定であることを表しています。ここに int
型にならない値を渡すと、わかりやすいメッセージを伴ってエラーが上がります。
parser.add_argument('files', nargs=2, type=argparse.FileType('r'), help='2 csv files.')
最後のこの行は実際の対象ファイルを指定するための引数を定義しています。 nargs
は引数の数を指定するものです。ここでは 2 つのファイルを比較したいので 2
を指定しています。 nargs
には、正の整数の他に '?'
( 0 個または 1 つ)や '*'
( 0 個以上)、 '+'
( 1 つ以上)、 argparse.REMAINDER
(残り全部)などを指定することができます。
以上です。
こちらのスクリプトに --help
オプションを指定して実行すると次のような出力が表示されます。わかりやすいですね。
$ python argparse_sample_2.py --help
usage: diff csv files. [-h] [-f {csv,tsv}] [-e {utf8,sjis}] [-v]
[-m MAX_LINES]
files files
positional arguments:
files 2 csv files.
optional arguments:
-h, --help show this help message and exit
-f {csv,tsv}, --format {csv,tsv}
file format (default: csv).
-e {utf8,sjis}, --encode {utf8,sjis}
file encoding.
-v, --verbose
-m MAX_LINES, --max-lines MAX_LINES
以上です。
規模の大きなツールを開発する場合には argparse
以外のオプションを検討した方がよいような気がしますが、ちょっとしたツールを作りたい場合であれば必要なものは argparse
でほぼほぼまかなえるのではないかと思います。
より詳しく知りたい方は公式ページなどをご覧になってみてください。