16.5. getopt — C 言語スタイルのコマンドラインオプションパーサ

ソースコード: Lib/getopt.py

注釈

getopt モジュールは、C 言語の getopt() 関数に慣れ親しんだ人ためにデザインされた API を持つコマンドラインオプションのパーサです。getopt() 関数に慣れ親しんでない人や、コードを少なくしてよりよいヘルプメッセージを表示させたい場合は、argparse モジュールの使用を検討してください。


このモジュールは sys.argv に入っているコマンドラインオプションの構文解析を支援します。'-' や '--' の特別扱いも含めて、Unix の getopt() と同じ記法をサポートしています。3番目の引数 (省略可能) を設定することで、GNU のソフトウェアでサポートされているような長形式のオプションも利用できます。

このモジュールは2つの関数と1つの例外を提供しています:

getopt.getopt(args, shortopts, longopts=[])

コマンドラインオプションとパラメータのリストを構文解析します。args は構文解析の対象になる引数のリストです。これは先頭のプログラム名を除いたもので、通常 sys.argv[1:] で与えられます。shortopts はスクリプトで認識させたいオプション文字と、引数が必要な場合にはコロン (':') をつけます。つまり Unix の getopt() と同じフォーマットになります。

注釈

GNU の getopt() とは違って、オプションでない引数の後は全てオプションではないと判断されます。これは GNUでない、Unix システムの挙動に近いものです。

longopts は長形式のオプションの名前を示す文字列のリストです。名前には、先頭の '--' は含めません。引数が必要な場合には名前の最後に等号 ('=') を入れます。オプション引数はサポートしていません。長形式のオプションだけを受けつけるためには、shortopts は空文字列である必要があります。長形式のオプションは、該当するオプションを一意に決定できる長さまで入力されていれば認識されます。たとえば、longopts['foo', 'frob'] の場合、--fo--foo にマッチしますが、--f では一意に決定できないので、GetoptError が送出されます。

返り値は2つの要素から成っています: 最初は (option, value) のタプルのリスト、2つ目はオプションリストを取り除いたあとに残ったプログラムの引数リストです (args の末尾部分のスライスになります)。それぞれの引数と値のタプルの最初の要素は、短形式の時はハイフン 1つで始まる文字列 (例: '-x')、長形式の時はハイフン2つで始まる文字列 (例: '--long-option') となり、引数が2番目の要素になります。引数をとらない場合には空文字列が入ります。オプションは見つかった順に並んでいて、複数回同じオプションを指定できます。長形式と短形式のオプションは混在できます。

getopt.gnu_getopt(args, shortopts, longopts=[])

この関数はデフォルトで GNU スタイルのスキャンモードを使う以外は getopt() と同じように動作します。つまり、オプションとオプションでない引数とを混在させることができます。getopt() 関数はオプションでない引数を見つけると解析を停止します。

オプション文字列の最初の文字を '+' にするか、環境変数 POSIXLY_CORRECT を設定することで、オプションでない引数を見つけると解析を停止するように振舞いを変えることができます。

exception getopt.GetoptError

引数リストの中に認識できないオプションがあった場合か、引数が必要なオプションに引数が与えられなかった場合に発生します。例外の引数は原因を示す文字列です。長形式のオプションについては、不要な引数が与えられた場合にもこの例外が発生します。 msg 属性と opt 属性で、エラーメッセージと関連するオプションを取得できます。特に関係するオプションが無い場合には opt は空文字列となります。

exception getopt.error

GetoptError へのエイリアスです。後方互換性のために残されています。

Unix スタイルのオプションを使った例です:

>>> import getopt
>>> args = '-a -b -cfoo -d bar a1 a2'.split()
>>> args
['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'abc:d:')
>>> optlist
[('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')]
>>> args
['a1', 'a2']

長形式のオプションを使っても同様です:

>>> s = '--condition=foo --testing --output-file abc.def -x a1 a2'
>>> args = s.split()
>>> args
['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'x', [
...     'condition=', 'output-file=', 'testing'])
>>> optlist
[('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')]
>>> args
['a1', 'a2']

スクリプト中での典型的な使い方は以下のようになります:

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError as err:
        # print help information and exit:
        print(err)  # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        elif o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-o", "--output"):
            output = a
        else:
            assert False, "unhandled option"
    # ...

if __name__ == "__main__":
    main()

argparse モジュールを使えば、より良いヘルプメッセージとエラーメッセージを持った同じコマンドラインインタフェースをより少ないコードで実現できます:

import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', '--output')
    parser.add_argument('-v', dest='verbose', action='store_true')
    args = parser.parse_args()
    # ... do something with args.output ...
    # ... do something with args.verbose ..

参考

argparse モジュール
別のコマンドラインオプションと引数の解析ライブラリ。