Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
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

cdsl
東京工科大学コンピュータサイエンス学部クラウド・分散システム研究室
https://www.tak-cslab.org/
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