tachitomonn’s blog

IT技術関連の学習メモがメインでたまに趣味のこととか

Python の argparseモジュール

Python の標準ライブラリに含まれるコマンドライン引数の解析モジュール argparse を公式ドキュメントのチュートリアルでお勉強。
Argparse チュートリアル — Python 3.8.2rc1 ドキュメント

基本

#! /usr/bin/env python

import argparse

parser = argparse.ArgumentParser()
parser.parse_args()

ArgumentParser のインスタンスを作成、 parse_argsメソッドでコマンドライン引数をパースするという理解で良いのかな。
このスクリプトを実行してみる。

>py -3 study_argparse.py

>py -3 study_argparse.py --help
usage: study_argparse.py [-h]

optional arguments:
  -h, --help  show this help message and exit

>py -3 study_argparse.py -v
usage: study_argparse.py [-h]
study_argparse.py: error: unrecognized arguments: -v

コマンドライン引数を与えないと何も表示されない。
ヘルプオプションは特に何も設定しなくても利用できる。
設定していないコマンドライン引数を与えると怒られる。

位置引数

#! /usr/bin/env python

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("positional", help="positional argument sample")
args = parser.parse_args()
print(args.positional)

実行すると、

>py -3 study_argparse.py
usage: study_argparse.py [-h] positional
study_argparse.py: error: the following arguments are required: positional

>py -3 study_argparse.py -h
usage: study_argparse.py [-h] positional

positional arguments:
  positional  positional argument sample

optional arguments:
  -h, --help  show this help message and exit

>py -3 study_argparse.py Hello!
Hello!

add_argumentメソッドで受け付けるコマンドライン引数を追加できる。
キーワード引数 help で当該引数の説明も書ける。
属性名のように追加引数を参照できる。

コマンドライン引数の型の指定もできる。デフォルトでは与えられた引数は文字列として扱われる。

#! /usr/bin/env python

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("positional", help="positional argument sample")
parser.add_argument("int_positional", help="positional argument sample", type=int)
args = parser.parse_args()
print(args.positional)
print(args.int_positional*10)

実行すると、

>py -3 study_argparse.py Hello! 1
Hello!
10

>py -3 study_argparse.py Hello! Hi!
usage: study_argparse.py [-h] positional int_positional
study_argparse.py: error: argument int_positional: invalid int value: 'Hi!'

オプション引数

#! /usr/bin/env python

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--optional", help="optional argument sample")
parser.add_argument("--optional_flg", help="optional argument sample", action="store_true")
args = parser.parse_args()
if args.optional:
    print("optional arg={}".format(args.optional))
if args.optional_flg:
    print("Bye!")

実行すると、

>py -3 study_argparse.py

>py -3 study_argparse.py -h
usage: study_argparse.py [-h] [--optional OPTIONAL] [--optional_flg]

optional arguments:
  -h, --help           show this help message and exit
  --optional OPTIONAL  optional argument sample
  --optional_flg       optional argument sample

>py -3 study_argparse.py --optional Hello! --optional_flg
optional arg=Hello!
Bye!

>py -3 study_argparse.py --optional Hello! --optional_flg Bye!
usage: study_argparse.py [-h] [--optional OPTIONAL] [--optional_flg]
study_argparse.py: error: unrecognized arguments: Bye!

「--」 を頭に付けるとオプション引数になる
キーワード引数 action に store_true を指定すると、自動的に True がセットされ、オプションが指定されなければ False がセットされることにより、該当オプションをフラグ化できる
フラグ化したオプションに値を指定すると怒られる

短いオプションも設定できる

#! /usr/bin/env python

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--optional", help="optional argument sample")
parser.add_argument("--optional_flg", help="optional argument sample", action="store_true")
parser.add_argument("-s", "--short_optional", help="optional argument sample", action="store_true")
args = parser.parse_args()
if args.optional:
    print("optional arg={}".format(args.optional))
if args.optional_flg:
    print("Bye!")
if args.short_optional:
    print("Yeah!")

実行すると、

>py -3 study_argparse.py -h
usage: study_argparse.py [-h] [--optional OPTIONAL] [--optional_flg] [-s]

optional arguments:
  -h, --help            show this help message and exit
  --optional OPTIONAL   optional argument sample
  --optional_flg        optional argument sample
  -s, --short_optional  optional argument sample

>py -3 study_argparse.py -s
Yeah!

位置引数とオプション引数の併用

#! /usr/bin/env python

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("positional", help="positional argument sample", type=int, choices=[1,2])
parser.add_argument("-s", "--short_optional", help="optional argument sample", action="store_true")
parser.add_argument("-d", "--default_optional", help="optional argument sample", default="Bye")
args = parser.parse_args()
print(args.positional*10)
if args.short_optional:
    print("Yeah!")
if args.default_optional:
    print(args.default_optional)

実行すると、

>py -3 study_argparse.py -h
usage: study_argparse.py [-h] [-s] [-d DEFAULT_OPTIONAL] {1,2}

positional arguments:
  {1,2}                 positional argument sample

optional arguments:
  -h, --help            show this help message and exit
  -s, --short_optional  optional argument sample
  -d DEFAULT_OPTIONAL, --default_optional DEFAULT_OPTIONAL
                        optional argument sample

>py -3 study_argparse.py -s 1
10
Yeah!
Bye

>py -3 study_argparse.py -s 2
20
Yeah!
Bye

>py -3 study_argparse.py -s 3
usage: study_argparse.py [-h] [-s] [-d DEFAULT_OPTIONAL] {1,2}
study_argparse.py: error: argument positional: invalid choice: 3 (choose from 1, 2)

>py -3 study_argparse.py -s -d Hello 1
10
Yeah!
Hello

併用は当然できる
キーワード引数 choices で受け付ける値を制限できる
キーワード引数 default でデフォルト値を設定できる

競合するオプションの指定

#! /usr/bin/env python

import argparse

parser = argparse.ArgumentParser(description="sample")
group = parser.add_mutually_exclusive_group()
group.add_argument("-r", "--right", help="optional argument sample", action="store_true")
group.add_argument("-l", "--left", help="optional argument sample", action="store_true")
args = parser.parse_args()
if args.right:
    print("Right")
elif args.left:
    print("Left")
else:
    print("Right? Left?")

parser.add_mutually_exclusive_groupメソッドで競合オプション用のグループを作って、そこに引数を追加する
あと、 ArgumentParser のインスタンス作成時にキーワード引数 description を使ってプログラムの説明を書ける
実行すると、

>py -3 study_argparse.py -h
usage: study_argparse.py [-h] [-r | -l]

sample

optional arguments:
  -h, --help   show this help message and exit
  -r, --right  optional argument sample
  -l, --left   optional argument sample

>py -3 study_argparse.py -r
Right

>py -3 study_argparse.py -l
Left

>py -3 study_argparse.py
Right? Left?

>py -3 study_argparse.py -r -l
usage: study_argparse.py [-h] [-r | -l]
study_argparse.py: error: argument -l/--left: not allowed with argument -r/--right