Python 3 で argparse を使ってサブコマンドをパースする方法を説明します。が、Python に詳しくないのでもっといい方法があるかもしれません。標準ライブラリだけで済ませたいけど、argparse は高機能過ぎて使いづらい…
やりたいこと
-
git
コマンドのようにgit add
やgit commit
を作る - サブコマンドごとのヘルプを見る
git help
を作る
サンプルコード
ポイントとしては次の通りです。
-
parser.add_subparsers()
でparser
を入れ子にする -
parser_〇〇.set_defaults(handler=関数名)
でサブコマンドごとの処理をハンドラ関数に移譲する - 未知のサブコマンドが指定された場合はヘルプを表示する
git.py
#!/usr/bin/env python
# coding: utf-8
import argparse
# サブコマンドの実際の処理を記述するコールバック関数
def command_add(args):
print(args)
def command_commit(args):
print(args)
def command_help(args):
print(parser.parse_args([args.command, '--help']))
# コマンドラインパーサーを作成
parser = argparse.ArgumentParser(description='Fake git command')
subparsers = parser.add_subparsers()
# add コマンドの parser を作成
parser_add = subparsers.add_parser('add', help='see `add -h`')
parser_add.add_argument('-A', '--all', action='store_true', help='all files')
parser_add.set_defaults(handler=command_add)
# commit コマンドの parser を作成
parser_commit = subparsers.add_parser('commit', help='see `commit -h`')
parser_commit.add_argument('-m', metavar='msg', help='commit message')
parser_commit.set_defaults(handler=command_commit)
# help コマンドの parser を作成
parser_help = subparsers.add_parser('help', help='see `help -h`')
parser_help.add_argument('command', help='command name which help is shown')
parser_help.set_defaults(handler=command_help)
# コマンドライン引数をパースして対応するハンドラ関数を実行
args = parser.parse_args()
if hasattr(args, 'handler'):
args.handler(args)
else:
# 未知のサブコマンドの場合はヘルプを表示
parser.print_help()
実行例
サブコマンドを指定しないと、トップレベルのヘルプメッセージが表示されます。
$ python git.py
usage: git.py [-h] {commit,add,help} ...
Fake git command
positional arguments:
{commit,add,help}
commit see `commit -h`
add see `add -h`
help see `help -h`
optional arguments:
-h, --help show this help message and exit
サブコマンドに -h
オプションを付けると、サブコマンドレベルのヘルプメッセージが表示されます。これは、argparse がよしなにやってくれるからです。
$ python git.py commit -h
usage: git.py commit [-h] [-m msg]
optional arguments:
-h, --help show this help message and exit
-m msg commit message
help
サブコマンドを使った場合も同様です。こちらは自前で実装したからです。
$ python git.py help commit
usage: git.py commit [-h] [-m msg]
optional arguments:
-h, --help show this help message and exit
-m msg commit message
最後に、 add
や commit
サブコマンドも期待通りに動作します。
$ python git.py add
Namespace(all=False, handler=<function command_add at 0x102973c80>)
$ python git.py commit -m "message"
Namespace(handler=<function command_commit at 0x10510e7b8>, m='message')