python argparse
argparse のドキュメントは説明が多すぎるので今後使いそうなやつまとめ。なお python の作法についてはあまり詳しくないのであしからず。
目次
- パーサーの初期化とヘルプメッセージ
- 真偽値のオプション
- 文字列のオプション
- 数値のオプション
- ファイル型のオプション
- 配列のオプション
- 位置引数
- パース
- サブコマンド
- リダイレクトやパイプで値を受け取る
パーサーの初期化とヘルプメッセージ
#!/usr/bin/env python3 # coding: utf-8 import argparse parser = argparse.ArgumentParser( prog='prog', # このプログラムの名前。 description='description', # usageとオプションとの間に表示するメッセージ epilog='epilog', # オプションの後、最後に表示されるメッセージ。copyrightとか付けたければ使うとよい # usage='of %(prog)s', # デフォルトの usage: から始まる行が気に入らない限り指定する必要ない # add_help=True, # -h/–help を追加する。ただしFalseを指定して無効化する以外は設定する必要ない ) parser.add_argument('-v', '--version', help='output version information', action='version', # versionを指定するとバージョンを表示後そのまま終了してくれる version='%(prog)s 2.0', # %(prog)s で prog='' に設定した名前を入れ込む ) parser.parse_args(['-h']) # 引数を空にすると sys.argv をパースする
ヘルプの出力結果。usage=
を設定しない場合 usage: prog [-h] [-v]
のようにいい感じにしてくれる。
usage: prog [-h] [-v] description optional arguments: -h, --help show this help message and exit -v, --version output version information epilog
真偽値のオプション
action
に store_false
を指定した場合は初期値が True
で、オプションを指定したら False
になる。store_true
は逆で初期値が False
。
parser.add_argument('-b', '--boolean', help='description', action='store_true', )
文字列のオプション
parser.add_argument('-s', '--string', help='description', # choicesを使って選択肢の中から値を受け取る # choices=['foo', 'bar', 'baz'], # 初期値を入れておくなら default で設定する default='hello', )
数値のオプション
parser.add_argument('-n', '--number', help='description', type=int, # floatにしたい場合は type=float choices=range(1, 10), # 許容する範囲を指定して簡単なバリデーションする # choices=[3,5,7], というようにリストでも指定できる metavar='1..10', # ヘルプの表示が変わる default=5, )
metavar
設定の有無による違い。
設定なし
usage: name [-h] [-v] [-n {1,2,3,4,5,6,7,8,9}] optional arguments: -n {1,2,3,4,5,6,7,8,9}, --number {1,2,3,4,5,6,7,8,9}
設定あり
usage: name [-h] [-v] [-n 1..10] optional arguments: -n 1..10, --number 1..10
ファイル型のオプション
parser.add_argument('-i', '--input', help='description', # rは読み込み。wなら書き込み。 type=open でもファイル型 type=argparse.FileType('r'), )
配列のオプション
# -a foo -a bar -a baz は ['foo', 'bar', 'baz'] というようにリストに追加されていく parser.add_argument('-a', '--array', help='description', action='append', )
位置引数
使う意味はあまりなさそう。オプション以外の引数。
nargs
に指定可能な値
?
はオプションとその値以外の最初の引数(残りの引数)*
とargparse.REMAINDER
は残りの引数がリストになる。 ただし残りの引数はargs, remain = parser.parse_known_args()
を使えばいいので必要ないと思う。数値
仕様も面倒くさそうだし、何に使うのか全くわからんので割愛
parser.add_argument('first', help='description', nargs='?', )
パース
#!/usr/bin/env python3 # coding: utf-8 import argparse parser = argparse.ArgumentParser( prog='prog', ) parser.add_argument('-v', '--version', help='Output version information', action='version', version='%(prog)s 2.0', ) # 真偽値 parser.add_argument('-b', '--boolean', help='description', action='store_true', ) # 整数値 parser.add_argument('-n', '--number', help='description', type=int, choices=range(1, 10), metavar='1..10', ) # ファイルの読み込み parser.add_argument('-i', '--input', help='description', type=argparse.FileType('r'), ) # 配列 parser.add_argument('-a', '--array', help='description', action='append', ) def main(): # args = parser.parse_args() # 残りの引数が必要ない場合はこれ # remain にはオプションとその値以外の残りの引数がリストで入ってる args, remain = parser.parse_known_args() print(args, remain) if args.boolean: print("boolean:", args.boolean) if args.number is not None: print("number:", args.number) if args.array is not None: print("array:", args.array) if args.input is not None: # data = args.input.read() for line in args.input: print(line.strip()) args.input.close() if __name__ == "__main__": try: main() except Exception as e: # エラーはexitコード 2 parser.error('Error: {}\n'.format(e)) else: parser.exit(0)
サブコマンド
参考: https://qiita.com/oohira/items/308bbd33a77200a35a3d
#!/usr/bin/env python3 # coding: utf-8 import argparse parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(dest='subcmd') subparser_add = subparsers.add_parser('add', help='see `add -h`') subparser_add.add_argument( '-A', '--all', action='store_true', help='all files') subparser_commit = subparsers.add_parser('commit', help='see `commit -h`') subparser_commit.add_argument( '-m', metavar='MESSAGE', help='commit message') args = parser.parse_args() if args.subcmd == None: # サブコマンドが指定されない場合はヘルプ表示する parser.print_help() # 参考記事のようにハンドラー関数を使わない場合の振り分け方 if args.subcmd == 'add': print('add!') elif args.subcmd == 'commit': print('commit!')
リダイレクトやパイプで値を受け取る
パイプ($ cat hello.txt | python main.py
) とか、リダイレクト($ python main.py < hello.txt
) でファイルを受け取る。
# is a tty が False のときは stdin に何か飛んでくる if not sys.stdin.isatty(): # lines = sys.stdin.readlines() for line in sys.stdin: print(line)