15.6. "getopt" --- C 言語スタイルのコマンドラインオプションパーサ
*****************************************************************

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

======================================================================

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

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

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

getopt.getopt(args, options[, long_options])

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

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

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

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

getopt.gnu_getopt(args, options[, long_options])

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

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

   バージョン 2.3 で追加.

exception getopt.GetoptError

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

   バージョン 1.6 で変更: "error" への別名として "GetoptError" が導入
   されました。

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 str(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" モジュール
     別のコマンドラインオプションと引数の解析ライブラリ。
