Python で引数を処理する argparse の基本的な使い方
Python で CLI ツールを作成する際、引数の処理には argparse が便利です。 argparse
の基本的な使い方を幾つかメモしておきます。
基本的な使い方
基本的には以下のような流れで利用します。
- パーサを作成する
- 引数を追加する
- 引数を処理する
サンプルコード
下記のサンプルコードでは arg1
という引数を追加しています。 これは自動的に必須引数になります。
| #!/usr/bin/env python
# coding: utf-8
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("arg1")
args = parser.parse_args()
print(args.arg1)
|
実行例
| # python3 sample.py Hello
Hello
|
任意のオプションを指定する
(必須では無い) 任意のオプションを指定する場合、add_argument を利用します。 -w
といったショートオプションを指定することも、--word
のようなロングオプションを指定することも、ショート / ロングの両オプションを指定することも可能です。
サンプルコード
| #!/usr/bin/env python
# coding: utf-8
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-w", "--word")
args = parser.parse_args()
if args.word != None:
print(args.word)
|
実行例
| # python3 sample.py --word Hello!
Hello!
|
True or False のフラグを指定する
True
または False
のフラグを利用するには引数に action="store_true"
または action="store_false"
を指定します。 各々、以下の違いがあります。
指定 |
オプション指定が無い場合のデフォルト値 |
オプション指定された場合の値 |
action="store_true" |
True |
False |
action="store_false" |
False |
True |
サンプルコード
| #!/usr/bin/env python
# coding: utf-8
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-a", action="store_true")
parser.add_argument("-b", action="store_false")
args = parser.parse_args()
print("a=" + str(args.a))
print("b=" + str(args.b))
|
実行例
| # python3 sample.py
a=False
b=True
|
| # python3 sample.py -a -b
a=True
b=False
|
デフォルト値を指定する
オプションが省略された際のデフォルト値は default で指定します。
サンプルコード
| #!/usr/bin/env python
# coding: utf-8
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--name", default="Alice")
args = parser.parse_args()
print(args.name)
|
実行例
| # python3 sample.py
Alice
|
| # python3 sample.py --name Bob
Bob
|
必須のオプションを指定する
サンプルコード
| #!/usr/bin/env python
# coding: utf-8
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--name", required=True)
args = parser.parse_args()
print("Hello, " + args.name + "!")
|
実行例
| # python3 sample.py
usage: sample.py [-h] --name NAME
sample.py: error: the following arguments are required: --name
|
| # python3 sample.py --name Alice
Hello, Alice!
|
型を指定する
オプションに代入される値の型を指定するには type を利用します。 type
が指定されない場合、値は「文字列」として扱われます。
サンプルコード
| #!/usr/bin/env python
# coding: utf-8
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--number", type=int)
parser.add_argument("--word", type=str)
args = parser.parse_args()
print(str(args.number))
print(args.word)
|
実行例
| # python3 sample.py --number 100 --word Hello!
100
Hello!
|
複数の選択肢から値を選ばせる
予め決められた複数の選択肢からいずれかの値を選択させるには choices を利用します。
サンプルコード
| #!/usr/bin/env python
# coding: utf-8
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--fruits", choices=["apple", "banana", "cherry"])
args = parser.parse_args()
print(args.fruits)
|
実行例
ヘルプは以下のように表示されます。
| # python3 sample.py --help
usage: sample.py [-h] [--fruits {apple,banana,cherry}]
options:
-h, --help show this help message and exit
--fruits {apple,banana,cherry}
|
選択肢に含まれている apple
は指定可能です。
| # python3 sample.py --fruits apple
apple
|
選択肢に含まれない pine
を指定するとエラーになります。
| # python3 sample.py --fruits pine
usage: sample.py [-h] [--fruits {apple,banana,cherry}]
sample.py: error: argument --fruits: invalid choice: 'pine' (choose from 'apple', 'banana', 'cherry')
|
このサンプルコードでは --fruits
オプションは必須では無く、任意です。 その為、値を指定しない場合は None
になります。
いずれかの値を必ず必要とする場合は required=True
なり default
を指定するなり、工夫します。
複数個の引数を受け取る
複数の引数を「ひとつのリスト」として受け取るには nargs="*" を利用します。
サンプルコード
| #!/usr/bin/env python
# coding: utf-8
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--fruits", nargs="*")
args = parser.parse_args()
print(args.fruits)
|
実行例
| # python3 sample.py --fruits apple
['apple']
|
| # python3 sample.py --fruits apple banana
['apple', 'banana']
|
| # python3 sample.py --fruits apple banana cherry
['apple', 'banana', 'cherry']
|
同時に指定出来ない、排他的なオプションを設定する
同時に指定出来ない (どれかひとつしか指定出来ない) オプションを設定するには add_mutually_exclusive_group を利用します。
サンプルコード
| #!/usr/bin/env python
# coding: utf-8
import argparse
parser = argparse.ArgumentParser(description="Sample Application")
group = parser.add_mutually_exclusive_group()
group.add_argument("-a", action="store_true")
group.add_argument("-b", action="store_false")
args = parser.parse_args()
|
実行例
オプション -a
だけを指定すれば実行出来ます。
オプション -b
だけを指定すれば実行出来ます。
オプション -a
と -b
を両方同時に指定するとエラーになります。
| # python3 sample.py -a -b
usage: sample.py [-h] [-a | -b]
sample.py: error: argument -b: not allowed with argument -a
|
ヘルプではこれらのオプションが排他的である旨は分かりませんので、分かりやすいヘルプの文面は自分で実装する必要があります。
| # python3 sample.py --help
usage: sample.py [-h] [-a | -b]
Sample Application
options:
-h, --help show this help message and exit
-a
-b
|
バージョン情報を表示する
argparse の action="version"
を利用することでバージョン情報を表示することが出来ます。
サンプルコード
| import argparse
parser = argparse.ArgumentParser(prog='Sample Application')
parser.add_argument('--version', action='version', version='%(prog)s 1.0.0')
args = parser.parse_args()
|
実行結果
| # python3 sample.py --version
Sample Application 1.0.0
|
1 階層 サブコマンドを実装する
例えば git clone
のように、メインコマンドに続くサブコマンドを実装するには ArgumentParse.add_subparsers を利用します。
サンプルコード
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | #!/usr/bin/env python
# coding: utf-8
import argparse
def cmd_sub1(args):
print("Subcommand1")
def cmd_sub2(args):
print("Subcommand2")
parser = argparse.ArgumentParser(description="Sample Application")
subparsers = parser.add_subparsers()
sub1 = subparsers.add_parser("sub1", help="Subcommand1")
sub1.add_argument("-a", action="store_true")
sub1.set_defaults(handler=cmd_sub1)
sub2 = subparsers.add_parser("sub2", help="Subcommand2")
sub2.add_argument("-b", action="store_true")
sub2.set_defaults(handler=cmd_sub2)
args = parser.parse_args()
if hasattr(args, "handler"):
args.handler(args)
else:
parser.print_help()
|
実行例
| # python3 sample.py sub1
Subcommand1
|
| # python3 sample.py sub2
Subcommand2
|
1
2
3
4
5
6
7
8
9
10
11
12 | # python3 sample.py
usage: sample.py [-h] {sub1,sub2} ...
Sample Application
positional arguments:
{sub1,sub2}
sub1 Subcommand1
sub2 Subcommand2
options:
-h, --help show this help message and exit
|
2 階層 サブコマンドを実装する
awscli の aws s3 ls
のように、サブコマンドに対して更にサブコマンドを指定出来る (サブコマンドが 2 階層以上になる) 場合は以下のように実装します。
サンプルコード
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | #!/usr/bin/env python
# coding: utf-8
import argparse
def cmd_sub2(args):
print("Subcommand2")
parser = argparse.ArgumentParser(description="Sample Application")
parser.set_defaults(command_help=parser.print_help)
subparsers1 = parser.add_subparsers()
sub1 = subparsers1.add_parser("sub1", help="Subcommand1")
parser.set_defaults(command_help=sub1.print_help)
subparsers2 = sub1.add_subparsers()
sub2 = subparsers2.add_parser("sub2", help="Subcommand2")
sub2.set_defaults(handler=cmd_sub2)
args = parser.parse_args()
if hasattr(args, "handler"):
args.handler(args)
else:
args.command_help()
|
実行例
| # python3 sample.py
usage: sample.py sub1 [-h] {sub2} ...
positional arguments:
{sub2}
sub2 Subcommand2
options:
-h, --help show this help message and exit
|
| # python3 sample.py sub1
usage: sample.py sub1 [-h] {sub2} ...
positional arguments:
{sub2}
sub2 Subcommand2
options:
-h, --help show this help message and exit
|
| # python3 sample.py sub1 sub2
Subcommand2
|
| # python3 sample.py sub1 sub2 --help
usage: sample.py sub1 sub2 [-h]
options:
-h, --help show this help message and exit
|
実行例
| # python3 sample.py
usage: sample.py [-h] {sub1} ...
Sample Application
positional arguments:
{sub1}
sub1 Subcommand1
options:
-h, --help show this help message and exit
|
| # python3 sample.py sub1
usage: sample.py [-h] {sub1} ...
Sample Application
positional arguments:
{sub1}
sub1 Subcommand1
options:
-h, --help show this help message and exit
|
| # python3 sample.py sub1 sub2
Subcommand2
|
共通オプションを指定する
基底になるパーサを作成し、それを引き継ぐ側で parents 指定することにより、共通オプションを指定することが可能です。 但し、基底になるパーサにヘルプ (-h
や --help
) が登録されていると、それを引き継いだ側と重複してしまう為、基底側では add_help=False
を指定してヘルプを登録しないようにしています。
サンプルコード
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | #!/usr/bin/env python
# coding: utf-8
import argparse
parser = argparse.ArgumentParser(description="Sample Application")
subparsers = parser.add_subparsers()
base = argparse.ArgumentParser(add_help=False)
base.add_argument("-c", "--common", action="store_true")
sub1 = subparsers.add_parser("sub1", help="Subcommand1", parents=[base])
sub1.add_argument("-a", action="store_true")
sub2 = subparsers.add_parser("sub2", help="Subcommand2", parents=[base])
sub2.add_argument("-b", action="store_true")
args = parser.parse_args()
|
実行例
sub1
サブコマンドのオプションは -c
と -a
です。 -c
が共通オプションです。
| # python3 sample.py sub1 --help
usage: sample.py sub1 [-h] [-c] [-a]
options:
-h, --help show this help message and exit
-c, --common
-a
|
sub2
サブコマンドのオプションは -c
と -b
です。 共通オプションである -c
がこちらにも登録されていることが分かります。
| # python3 sample.py sub2 --help
usage: sample.py sub2 [-h] [-c] [-b]
options:
-h, --help show this help message and exit
-c, --common
-b
|
オプションをヘルプ表示時、グループ化する
ヘルプを表示する際、add_argument_group を使うことでオプションごとにグループ化して表示することが出来ます。 用途は様々ですが、例えば「サブコマンド実装時、共通コマンドは global options
としてグループ化して表示」する実装例は以下の通りです。
サンプルコード
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | #!/usr/bin/env python
# coding: utf-8
import argparse
parser = argparse.ArgumentParser(description="Sample Application")
subparsers = parser.add_subparsers()
base = argparse.ArgumentParser(add_help=False)
group = base.add_argument_group("global options")
group.add_argument("-c", "--common", action="store_true", help="Common option")
sub1 = subparsers.add_parser("sub1", help="Subcommand1", parents=[base])
sub1.add_argument("-a", action="store_true")
sub2 = subparsers.add_parser("sub2", help="Subcommand2", parents=[base])
sub2.add_argument("-b", action="store_true")
args = parser.parse_args()
|
実行例
| # python3 sample.py sub1 --help
usage: sample.py sub1 [-h] [-c] [-a]
options:
-h, --help show this help message and exit
-a
global options:
-c, --common Common option
|
| # python3 sample.py sub2 --help
usage: sample.py sub2 [-h] [-c] [-b]
options:
-h, --help show this help message and exit
-b
global options:
-c, --common Common option
|