コマンドライン引数をどう処理するか(3つの方法)

コマンドライン引数の処理の方法を調べる。3つ方法がある(sys.argvを使うか、getoptを使うか、またはoptparseを使うか)。
使い捨てのスクリプトでは、基本的なsys.argvで済まし、凝ったソフトウェアでは、optparseで実装するのがきれいにコードが書けるのではないか、というのが結論。

基本

sysモジュールを使う。sys.argvにリストとして格納されるので、簡単に引数を取り出せる。以下のように書ける。

# argv.py
def main(a):
    print a

if __name__ == '__main__':
    import sys
    main(sys.argv)

実行例は以下の通り。

$ python args.py 1 a
['args.py', '1', 'a']

getoptモジュール

もうちょっと実用的な引数の指定をするときには、getoptモジュールを使う。getopt.getopt関数を使ったコードの例は下の通り。

# getargs.py
def main(o, a):
    for option, value in o:
        if option in ('-h', '--help'):
            print 'usage:...'
        elif option in ('-d', '--directory'):
            directory = value
        elif option in ('-i', '--confirm'):
            confirm = True

if __name__ == '__main__':
    import sys
    import getopt
    try:
        options, args = getopt.getopt(sys.argv[1:],
                    'hd:i', ['help', 'directory=', 'confirm'])
        main(options, args)
    except getopt.GetoptError:
        print 'given options are not correct.'
        sys.exit(0)
  • sys.argv[1:]がパースする引数のリスト
  • 2番目の引数('hd:i')で"ハイフン+一文字"で与えるオプションを指定している。ここでは、"-h"、"-d"、"-i"がオプションとして許される。-セミコロン"d:"は、"-d"が一つ引数を取ることを意味する。"-d something"の形で与える。"-d=something"と指定すると、dの引数として、"=something"を与えることになるので注意。
  • 3番目の引数で、一文字以上のオプションをリストで並べる。ここでは、"--help"、"--directory"、"--confirm"がオプションとして指定できることになる。"direcotry="のイコールは、"--directory"オプションが引数を一つ取ることを意味する。"--directory=/hoge"、"--directory hoge"の形で与える。何にも引数を与えないと、getopt.GetoptErrorになる。
  • getopt関数は、タプル(options, args)を返す。optionsは、与えられたオプションとその引数のリストである。argsは、オプション以外の与えられた引数のリストである。指定していないオプションを与えた場合、getopt.GetoptErrorになり、その値はargsには格納されない。

実行例は以下の通り。

$ python getargs.py --help -d hoge --confirm file1.txt
$ python getargs.py --directory hoge --confirm file1.txt
$ python getargs.py --directory=/hoge --confirm file1.txt file2.tx

optparseモジュール

getoptよりさらに便利なモジュールが、optparse。このモジュールの使い方の例は以下の通り。

#optparse_example.py
def main(o, a):
    if o.directory != None:
        directory = o.directory
    if o.confirm:
        confirm = True

if __name__ == '__main__':
    import sys
    from optparse import OptionParser

    parser = OptionParser()
    parser.add_option('-d', '--directory', dest='directory',
                      help='destination directory')
    parser.add_option('-i', '--confirm', dest='confirm',
                      action='store_true', default=False,
                      help='confirm each move')
    options, args = parser.parse_args(sys.argv[1:])

    main(options, args)
  • add_optionでオプションを定義していく。1番目と2番目の引数で短いオプションと長いオプションを設定する。
  • "dest"キーワードは、オプションの引数を格納する場所。例えば、options.directoryで"-d"オプションの引数にアクセスできる。optionsはparse_argsの返り値。
  • "help"キーワードは、"-h"や"--help"オプションを指定したときに、表示される文字列を与える。つまり、"-h"オプションは、add_optionで明示的に定義する必要がない。この点で、getoptより楽。
  • action='store_true'と指定されると、"-i"、"--confirm"オプションは値を取らずに、booleanとしてふるまう。このオプションが指定されると、options.confirm=Trueとなる。

実行例は以下の通り。

$ python optparse_example.py --help
Usage: args2.py [options]

Options:
  -h, --help            show this help message and exit
  -d DIRECTORY, --directory=DIRECTORY
                        destination directory
  -i, --confirm         confirm each move