Help us understand the problem. What is going on with this article?

Pythonでコマンドラインオプションを処理する

More than 1 year has passed since last update.

TUT Advent Calendar 2018の24日目の記事です。遅刻してごめんなさい。

print('🙏'*100)

TL;DR

Pythonでコマンドライン引数をdict(辞書)に置き換える。

実装方法

1. argparseを使う

16.4. argparse — コマンドラインオプション、引数、サブコマンドのパーサー — Python 3.6.5 ドキュメント

argparseを使ったサンプル
import argparse

parser = argparse.ArgumentParser(description='Parse command line options.')
parser.add_argument('integers', metavar='c', type=int, nargs='+',
                    help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
                    const=sum, default=max,
                    help='sum the integers (default: find the max)')

args = parser.parse_args(['--sum', '7', '-1', '42'])
print(args.accumulate(args.integers))

2. optparseを使う

36.1. optparse — コマンドラインオプション解析器 — Python 3.6.5 ドキュメント

optparseを使ったサンプル
from optparse import OptionParser

parser = OptionParser()
parser.add_option("-f", "--file", dest="filename",
                  help="write report to FILE", metavar="FILE")
parser.add_option("-q", "--quiet",
                  action="store_false", dest="verbose", default=True,
                  help="don't print status messages to stdout")

(options, args) = parser.parse_args()

3. argparse vs. optparse

結論: argparse がv3.2から追加された為、理由がなければargparseを使うのがよい。

もともと、argparse モジュールは optparse モジュールとの互換性を保って開発しようと試みられました。しかし、特に新しい nargs= 指定子とより良い使用法メッセージのために必要な変更のために、optparse を透過的に拡張することは難しかったのです。optparse のほとんどすべてがコピーアンドペーストされたりモンキーパッチを当てられたりしたとき、もはや後方互換性を保とうとすることは現実的ではありませんでした。argparse モジュールは標準ライブラリ optparse モジュールを、以下を含むたくさんの方法で改善しています:

出典: 16.4.6. optparse からのアップグレード — Python 3.6.5 ドキュメント

4. 自分で書く

コマンドライン引数を「 - から始まる文字列であるか」で判定している。' -'で引数を分割してdictに代入している。

ソース: arg.py - gist

arg.py
import sys
import re

def main(args):
    params = {}
    args = (' ' + ' '.join(args)).split(' -')
    args = [a for a in args if a] # remove blank elements

    for arg in args:
        split_arg = arg.split(' ')
        key = re.sub('^-*', '', split_arg[0])
        val = ' '.join(split_arg[1:])
        params[key] = val

    print(params)

if __name__ == '__main__':
    # main(sys.argv[1:])
    main("-e 222 -c foo -t bar --hoge --piyo moge".split(' '))
実行結果
$ python3 arg.py -c 100 -f sample.txt -w word
{'c': '100', 'f': 'sample.txt', 'w': 'word'}

まとめ

Pythonでコマンドライン引数を扱う方法は大きく分けると3つある。

  1. argparseを使う
  2. optparseを使う
  3. 自分で実装する

簡単に実現するなら argparse を使うのがよい。単純なデータ整形であれば、自分で実装しても大変ではない。


Copyright (c) 2018 Tomoyuki KOYAMA
Released under the MIT license
http://opensource.org/licenses/mit-license.php

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした