【python】コマンドライン引数を扱うargparseを丁寧に

はじめに

本記事では,argparseを用いてコマンドライン引数を便利に使う方法を紹介します.

公式ドキュメントはこちら:argparse --- コマンドラインオプション、引数、サブコマンドのパーサー — Python 3.9.1 ドキュメント

目次

argparseは何ができるか

コマンドライン引数を簡単に参照できるようになります.コマンドライン引数は,実行時に与える情報のことです.例えば,以下の例ではファイルのパスをコマンドライン引数で与えています.

python sample.py --in_file desktop/hoge.txt

argparseのインポート

インポートは一行です.

import argparse

argparseの最小限サンプル

まずは最小限のサンプルをみて,構成を確認します.

基本的に,

  1. 引数を解析するためのArgumentParserインスタンスを作成
  2. 必要なオプションを.add_argument()で追加
  3. .parse_args()で引数の解析結果を取得.

という構成です.1.と3.はいつも同じなので,役割は一旦気にせず,そういうものだと思っても良いです.

# コード (sample.py)
import argparse

parser = argparse.ArgumentParser() # 1.インスタンスの作成
parser.add_argument('--in_file') # 2.必要なオプションを追加
args = parser.parse_args() # 3.オプションを解析
print(args.in_file)
# with open(args.in.file) as fp: みたいに使ったりとか

このようなプログラムを実行する場合,プログラム名をsample.pyだとすると

python sample.py --in_file desktop/sample.txt
# 出力: desktop/hoge.txt

のように実行できます.add_argument()'--in_file'の引数を追加しているので,実行時に指定できるようになりました.また,プログラム上ではargs.in_fileのように,変数名として使用できています.今回はそのまま出力しているので,ファイルパス(だと思っている文字列)が出力されます.プログラムは一切書き換えずに入力を変えられるのが嬉しいポイントです.

引数の一覧を表示する: --help

--helpもしくは-hコマンドライン引数の一覧を確認できます.--helpはデフォルトで使えるため,add_argument()で追加する必要はありません.

主に他人が作ったプログラムを使おうとするときに,そもそもどんな引数を取るか知るために使います.

# コード (sample.py)
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--sample1')
parser.add_argument('--sample2')
parser.add_argument('--sample3')
args = parser.parse_args()
# 実行
python sample.py -h
# 出力(使える引数が表示される)
usage: sample.py [-h] [--sample1 SAMPLE1] [--sample2 SAMPLE2] [--sample3 SAMPLE3]

optional arguments:
  -h, --help         show this help message and exit
  --sample1 SAMPLE1
  --sample2 SAMPLE2
  --sample3 SAMPLE3

add_argument()の詳細設定

引数の説明文を追加する(help='')

help=文字列で,設定したコマンドライン引数の説明文を追加できます.

# コード (sample.py)
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--in_file', help='入力ファイルのパスです.')
args = parser.parse_args()

こうしておくと,--helpで引数の一覧を表示したときに説明文が表示されます.

usage: sample.py [-h] [--in_file IN_FILE]

optional arguments:
  -h, --help         show this help message and exit
  --in_file IN_FILE  入力ファイルのパスです.

引数を必須にする(required=True)

required=Trueを設定すると,その引数は必須になります.

# コード (sample.py)
import argparse

parser = argparse.ArgumentParser() 
parser.add_argument('--in_file', required=True)
args = parser.parse_args()
print(args.in_file)

この引数を無視して実行しようとすると,

# 実行
python sample.py

エラーが出ます.

# 出力
usage: sample.py [-h] --in_file IN_FILE
sample.py: error: the following arguments are required: --in_file

引数の型を決める(type=)

type=で引数の型を変換してくれます.コマンドライン引数はデフォルトで文字列として扱われますが,整数や実数で扱いたいとき,これを使います.

# コード (sample.py)
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--str_arg')
parser.add_argument('--int_arg', type=int)
args = parser.parse_args()
print('str_arg:', args.str_arg, type(args.str_arg))
print('int_arg:', args.int_arg, type(args.int_arg))
# 実行
python3 sample.py --str_arg 10 --int_arg 10
# 出力
str_arg: 10 <class 'str'>
int_arg: 10 <class 'int'>

bool値で設定する(action='store_true')

action='store_true' で,引数をbool値で設定することができます.

よく使われる場面として,計算の途中経過を出力するかどうかを指定する--verboseが挙げられます(verboseは「冗長な」という意味).使い方は,--verbose を指定するかしないかです.

同じような設定にaction='store_false'もありますが,ややこしくなるだけなので基本的には指定すればtrueになるこちらを使いましょう.

# コード (sample.py)
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--verbose', action='store_true')
args = parser.parse_args()
if args.verbose:
    print('途中経過が出力されるよ')
else:
    print('途中経過は出力されないよ')
python sample.py --verbose
# 途中経過が出力されるよ
python sample.py
# 途中経過は出力されないよ

引数として許される値を設定する(choices=)

引数によっては,許す値の候補を提示したいときがあります.例えば,果物の名前を指定する引数に Apple, Orange は許したいが,それ以外の果物,例えばGrapeは許さない,というような場合です.このようなとき,choices=[許す値のリスト] とすることで実現できます.

# コード (sample.py)
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--fruit', choices=['Apple', 'Orange'])
args = parser.parse_args()
print(args.str)
# 実行例1 (適切な値を指定)
python3 sample.py --fruit Apple
# Apple
# 実行例2(不適切な値を指定)
python3 sample.py --fruit Grape
usage: sample.py [-h] [--fruit {Apple,Orange}]
sample.py: error: argument --fruit: invalid choice: 'Grape' (choose from 'Apple', 'Orange')

引数のデフォルト値を設定する(default=)

引数のデフォルト値を default=値で設定できます.プログラムを実行する際にオプションで指定されなかったとき,ここで設定した値が使われます.

# コード (sample.py)
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--x', default=10)
args = parser.parse_args()
print(args.x)
# 実行例1(デフォルト値を使用)
python3 sample.py
# 10
# 実行例2(オプションで指定されたので,その値を使用)
python3 nlp.py --x 20
# 20

一つの引数に与えられる数を設定する(nargs=)

コマンドライン引数の数」ではなくて,「一つのコマンドライン引数に与えられる数」であることに注意してください.

nargs=を指定することで,一つの引数に複数個の値を与えられます.プログラム上ではリストになります.nargs=には'*''+',もしくは具体的な数字を入れることができて,入力として許容する個数を表します.正規表現を知っている人は,まさに記号通りの意味で分かりやすいと思います.

  • nargs='*': 0個以上を許容します.
# コード (sample.py)
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--numbers', nargs='*')
args = parser.parse_args()
print(args.numbers)
# 実行例1(3個与えてみる)
python3 sample.py --numbers 1 2 3
# 出力
['1', '2', '3']
# 実行例2(0個与えてみる)
python3 sample.py --numbers
# 出力
[]
  • nargs='+': 1個以上を許容します.
# コード (sample.py)
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--numbers', nargs='+')
args = parser.parse_args()
print(args.numbers)
# 実行例1(3個与えてみる)
python3 sample.py --numbers 1 2 3
# 出力
['1', '2', '3']
# 実行例2(0個与えてみる)
python3 sample.py --numbers
# 出力(エラー)
usage: sample.py [-h] [--numbers NUMBERS [NUMBERS ...]]
sample.py: error: argument --numbers: expected at least one argument
  • nargs='具体的な数': 指定した個数ちょうどだけ許容します.
# コード (sample.py)
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--numbers', nargs=2) # 2個だけ許容
args = parser.parse_args()
print(args.numbers)
# 実行例(2個与えてみる)
python3 sample.py --numbers 1 2
# 出力
['1', '2']
# 実行例1(3個与えてみる)
python3 sample.py --numbers 1 2 3
# 出力(エラー)
usage: sample.py [-h] [--numbers NUMBERS NUMBERS]
sample.py: error: unrecognized arguments: 3

実は他にも2種類を指定できますが,割愛します.

(詳細: https://docs.python.org/ja/3/library/argparse.html#nargs