Python のコマンドライン引数ライブラリの主なものを表にしました。
ライブラリ名 | Python同梱 | 型変換 | デフォルト値 | 自動ヘルプ | 位置引数 | サブコマンド |
---|---|---|---|---|---|---|
getopt | 1.4〜 | |||||
optparse | 2.3〜 | オプションのみ | ||||
argparse | 2.7〜 3.2〜 | |||||
docopt | 明記 | 手動ヘルプ、ていうか設定が自動 | 手動 |
現在は実質、argparse か docopt の二択ですね。
元は、python -V
とか mysql --version
みたいな、コマンドラインオプションを argv
から切り分けるために C の getopt を借用。その後、使いやすさを向上させる、optparse が採用されました。
が、そもそも機能的なサポートがオプション引数だけでいいのか、ということで、mv <form> <to>
みたいに順序で指定する通常のコマンドライン引数までカバーできる argparse の導入。
ここまでは Python に同梱されるライブラリの世界。こういう感じ:
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument(
'integers',
metavar='N',
type=int,
nargs='+',
help='an integer for the accumulator'
)
parser.add_argument(
'--sum',
action='store_true',
help='sum the integers (default: find the max)'
)
args = parser.parse_args()
if args.sum:
print(sum(args.integers))
else:
print(max(args.integers))
$ python argparse-test.py -h
usage: argparse-test.py [-h] [--sum] N [N ...]
Process some integers.
positional arguments:
N an integer for the accumulator
optional arguments:
-h, --help show this help message and exit
--sum sum the integers (default: find the max)
$ python argparse-test.py 1 2
2
$ python argparse-test.py 1 2 --sum
3
argparse までくるとけっこう高級化していて、使いこなすのがたいへん。けど、こんな高級なのでも今の Python になら最初から同梱されてるので、ライブラリバージョン間で仕様がぶれる心配がなく、マニュアルもちゃんとある安心感はありがたいです。
この機能性向上に対して、ちょっと別角度から面白いのが docopt です。
"""Usage: docopt-test.py [-h] [--sum] N [N ...]
Process some integers.
Arguments:
N an integer for the accumulator
Options:
-h, --help show this help message and exit
--sum sum the integers (default: find the max)
"""
from docopt import docopt
args = docopt(__doc__) # __doc__ は現在のソースに対応する doc ブロックの内容
integers = map(int, args.get('N'))
if args.get('--sum'):
print(sum(integers))
else:
print(max(integers))
ドキュメント文字列をパースして引数解釈の仕様を起こす感じ。「仕様を書くだけでコードになる」 を地でいっててかっこいいですね。
実行しなくてもヘルプが読めるので、GitHub なんかの上でも、どういうツールかがわかります。別途ドキュメントを書かなくても、というか、動きと一致した正しいドキュメントを書かないと成り立たない、ので、後から追加した隠しオプションのドキュメントがなくて忘れられていたとか、なくなりそう。
まあ、 map(int, args.get('N'))
みたいに、型変換などの高級な機能は手動でしてやらないと、なんせ doc には書けないので。って感じで、機能の量でいけば argparse の置き換えとしては役不足ですが。 (ま、入力データは文字列、バリデーションはバリデーションのライブラリで、ってなってても、Web屋の自分にはしっくり来るけど)
自分が気に入ったのは docopt の書式が各言語間で共通だということ。
最初 Python で書いておくけど、後からそのままの仕様で Go や Rust で実装したり、あるいは既存 Web システムとの協調性を意識して PHP や Ruby に同じインターフェースで移植したり、ありますよね。