36.1. optparse — コマンドラインオプション解析器

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

バージョン 3.2 で撤廃: optparse モジュールは廃止予定であり、これ以上の開発は行われません。argparse モジュールを使用してください。


optparse モジュールは、昔からある getopt よりも簡便で、柔軟性に富み、かつ強力なコマンドライン解析ライブラリです。 optparse では、より宣言的なスタイルのコマンドライン解析手法、すなわち OptionParser のインスタンスを作成してオプションを追加してゆき、そのインスタンスでコマンドラインを解析するという手法をとっています。 optparse を使うと、GNU/POSIX 構文でオプションを指定できるだけでなく、使用法やヘルプメッセージの生成も行えます。

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()

このようにわずかな行数のコードによって、スクリプトのユーザはコマンドライン上で例えば以下のような「よくある使い方」を実行できるようになります:

<yourscript> --file=outfile -q

コマンドライン解析の中で、 optparse はユーザの指定したコマンドライン引数値に応じて parse_args() の返す options の属性値を設定してゆきます。 parse_args() がコマンドライン解析から処理を戻したとき、 options.filename"outfile" に、 options.verboseFalse になっているはずです。 optparse は長い形式と短い形式の両方のオプション表記をサポートしており、短い形式は結合して指定できます。また、様々な形でオプションに引数値を関連付けられます。従って、以下のコマンドラインは全て上の例と同じ意味になります:

<yourscript> -f outfile --quiet
<yourscript> --quiet --file outfile
<yourscript> -q -foutfile
<yourscript> -qfoutfile

さらに、ユーザが以下のいずれかを実行すると

<yourscript> -h
<yourscript> --help

optparse はスクリプトのオプションについて簡単にまとめた内容を出力します:

Usage: <yourscript> [options]

Options:
  -h, --help            show this help message and exit
  -f FILE, --file=FILE  write report to FILE
  -q, --quiet           don't print status messages to stdout

yourscript の中身は実行時に決まります (通常は sys.argv[0] になります)。

36.1.1. 背景

optparse は、素直で慣習に則ったコマンドラインインタフェースを備えたプログラムの作成を援助する目的で設計されました。その結果、Unix で慣習的に使われているコマンドラインの構文や機能だけをサポートするに留まっています。こうした慣習に詳しくなければ、よく知っておくためにもこの節を読んでおきましょう。

36.1.1.1. 用語集

argument

コマンドラインでユーザが入力するテキストの塊で、シェルが execlexecv に引き渡すものです。Python では、引数は sys.argv[1:] の要素となります。(sys.argv[0] は実行しようとしているプログラムの名前です。引数解析に関しては、この要素はあまり重要ではありません。) Unix シェルでは、「語 (word)」という用語も使います。

場合によっては sys.argv[1:] 以外の引数リストを代入する方が望ましいことがあるので、「引数」は「 sys.argv[1:] または sys.argv[1:] の代替として提供される別のリストの要素」と読むべきでしょう。

option

追加的な情報を与えるための引数で、プログラムの実行に対する教示やカスタマイズを行います。オプションには多様な文法が存在します。伝統的な Unix における書法はハイフン (“-”) の後ろに一文字が続くもので、例えば -x-F です。また、伝統的な Unix における書法では、複数のオプションを一つの引数にまとめられます。例えば -x -F-xF と等価です。 GNU プロジェクトでは -- の後ろにハイフンで区切りの語を指定する方法、例えば --file--dry-run も提供しています。 optparse は、これら二種類のオプション書法だけをサポートしています。

他に見られる他のオプション書法には以下のようなものがあります:

  • ハイフンの後ろに数個の文字が続くもので、例えば -pf (このオプションは複数のオプションを一つにまとめたものとは 違います)

  • ハイフンの後ろに語が続くもので、例えば -file (これは技術的には上の書式と同じですが、通常同じプログラム上で一緒に使うことはありません)

  • プラス記号の後ろに一文字、数個の文字、または語を続けたもので、例えば +f, +rgb

  • スラッシュ記号の後ろに一文字、数個の文字、または語を続けたもので、例えば /f, /file

上記のオプション書法は optparse ではサポートしておらず、今後もサポートする予定はありません。これは故意によるものです: 最初の三つはどの環境の標準でもなく、最後の一つは VMS や MS-DOS, そして Windows を対象にしているときにしか意味をなさないからです。

オプション引数

あるオプションの後ろに続く引数で、そのオプションに密接な関連をもち、オプションと同時に引数リストから取り出されます。 optparse では、オプション引数は以下のように別々の引数にできます:

-f foo
--file foo

また、一つの引数中にも入れられます:

-ffoo
--file=foo

通常、オプションは引数をとることもとらないこともあります。あるオプションは引数をとることがなく、またあるオプションは常に引数をとります。多くの人々が「オプションのオプション引数」機能を欲しています。これは、あるオプションが引数が指定されている場合には引数をとり、そうでない場合には引数をもたないようにするという機能です。この機能は引数解析をあいまいにするため、議論の的となっています: 例えば、もし -a がオプション引数をとり、 -b がまったく別のオプションだとしたら、 -ab をどうやって解析すればいいのでしょうか?こうした曖昧さが存在するため、 optparse は今のところこの機能をサポートしていません。

位置引数

他のオプションが解析される、すなわち他のオプションとその引数が解析されて引数リストから除去された後に引数リストに置かれているものです。

必須のオプション

コマンドラインで与えなければならないオプションです; 「必須のオプション (required option)」という語は、英語では矛盾した言葉です。 optparse では必須オプションの実装を妨げてはいませんが、とりたてて実装上役立つこともしていません。

例えば、下記のような架空のコマンドラインを考えてみましょう:

prog -v --report report.txt foo bar

-v--report はどちらもオプションです。--report オプションが引数をとるとすれば、report.txt はオプションの引数です。foobar は固定引数になります。

36.1.1.2. オプションとは何か

オプションはプログラムの実行を調整したり、カスタマイズしたりするための補助的な情報を与えるために使います。もっとはっきりいうと、オプションはあくまでもオプション (省略可能)であるということです。本来、プログラムはともかくもオプションなしでうまく実行できてしかるべきです。(Unix やGNU ツールセットのプログラムをランダムにピックアップしてみてください。オプションを全く指定しなくてもちゃんと動くでしょう?例外は find, tar, dd くらいです—これらの例外は、オプション文法が標準的でなく、インタフェースが混乱を招くと酷評されてきた変種のはみ出しものなのです)

多くの人が自分のプログラムに「必須のオプション」を持たせたいと考えます。しかしよく考えてください。必須なら、それは オプション(省略可能) ではないのです! プログラムを正しく動作させるのに絶対的に必要な情報があるとすれば、そこには固定引数を割り当てるべきなのです。

良くできたコマンドラインインタフェース設計として、ファイルのコピーに使われる cp ユーティリティのことを考えてみましょう。ファイルのコピーでは、コピー先を指定せずにファイルをコピーするのは無意味な操作ですし、少なくとも一つのコピー元が必要です。従って、cp は引数無しで実行すると失敗します。とはいえ、cp はオプションを全く必要としない柔軟で便利なコマンドライン文法を備えています:

cp SOURCE DEST
cp SOURCE ... DEST-DIR

まだあります。ほとんどの cp の実装では、ファイルモードや変更時刻を変えずにコピーする、シンボリックリンクの追跡を行わない、すでにあるファイルを上書きする前にユーザに尋ねる、など、ファイルをコピーする方法をいじるための一連のオプションを実装しています。しかし、こうしたオプションは、一つのファイルを別の場所にコピーする、または複数のファイルを別のディレクトリにコピーするという、cp の中心的な処理を乱すことはないのです。

36.1.1.3. 固定引数とは何か

固定引数とは、プログラムを動作させる上で絶対的に必要な情報となる引数です。

よいユーザインタフェースとは、可能な限り少ない固定引数をもつものです。プログラムを正しく動作させるために 17 個もの別個の情報が必要だとしたら、その 方法 はさして問題にはなりません —ユーザはプログラムを正しく動作させられないうちに諦め、立ち去ってしまうからです。ユーザインタフェースがコマンドラインでも、設定ファイルでも、GUI やその他の何であっても同じです: 多くの要求をユーザに押し付ければ、ほとんどのユーザはただ音をあげてしまうだけなのです。

要するに、ユーザが絶対に提供しなければならない情報だけに制限する — そして可能な限りよく練られたデフォルト設定を使うよう試みてください。もちろん、プログラムには適度な柔軟性を持たせたいとも望むはずですが、それこそがオプションの果たす役割です。繰り返しますが、設定ファイルのエントリであろうが、GUI でできた「環境設定」ダイアログ上のウィジェットであろうが、コマンドラインオプションであろうが関係ありません — より多くのオプションを実装すればプログラムはより柔軟性を持ちますが、実装はより難解になるのです。高すぎる柔軟性はユーザを閉口させ、コードの維持をより難しくするのです。

36.1.2. チュートリアル

optparse はとても柔軟で強力でありながら、ほとんどの場合には簡単に利用できます。この節では、 optparse ベースのプログラムで広く使われているコードパターンについて述べます。

まず、OptionParser クラスを import しておかなければなりません。次に、プログラムの冒頭で OptionParser インスタンスを生成しておきます:

from optparse import OptionParser
...
parser = OptionParser()

これでオプションを定義できるようになりました。基本的な構文は以下の通りです:

parser.add_option(opt_str, ...,
                  attr=value, ...)

各オプションには、 -f--file のような一つまたは複数のオプション文字列と、パーザがコマンドライン上のオプションを見つけた際に、何を準備し、何を行うべきかを optparse に教えるためのオプション属性 (option attribute)がいくつか入ります。

通常、各オプションには短いオプション文字列と長いオプション文字列があります。例えば:

parser.add_option("-f", "--file", ...)

オプション文字列は、(ゼロ文字の場合も含め)いくらでも短く、またいくらでも長くできます。ただしオプション文字列は少なくとも一つなければなりません。

OptionParser.add_option() に渡されたオプション文字列は、実際にはこの関数で定義したオプションに対するラベルになります。簡単のため、以後ではコマンドライン上で オプションを見つける という表現をしばしば使いますが、これは実際には optparse がコマンドライン上の オプション文字列 を見つけ、対応づけされているオプションを探し出す、という処理に相当します。

オプションを全て定義したら、 optparse にコマンドラインを解析するように指示します:

(options, args) = parser.parse_args()

(お望みなら、 parse_args() に自作の引数リストを渡してもかまいません。とはいえ、実際にはそうした必要はほとんどないでしょう: optionparser はデフォルトで sys.argv[1:] を使うからです。)

parse_args() は二つの値を返します:

  • 全てのオプションに対する値の入ったオブジェクト options — 例えば、--file が単一の文字列引数をとる場合、options.file はユーザが指定したファイル名になります。オプションを指定しなかった場合には None になります

  • オプションの解析後に残った固定引数からなるリスト args

このチュートリアルの節では、最も重要な四つのオプション属性: action, type, dest (destination), help についてしか触れません。このうち最も重要なのは action です。

36.1.2.1. オプション・アクションを理解する

アクション(action)は optparse がコマンドライン上にあるオプションを見つけたときに何をすべきかを指示します。 optparse には押し着せのアクションのセットがハードコードされています。新たなアクションの追加は上級者向けの話題であり、 optparse の拡張 で触れます。ほとんどのアクションは、値を何らかの変数に記憶するよう optparse に指示します — 例えば、文字列をコマンドラインから取り出して、 options の属性の中に入れる、といった具合にです。

オプション・アクションを指定しない場合、 optparse のデフォルトの動作は store になります。

36.1.2.2. store アクション

もっとも良く使われるアクションは store です。このアクションは次の引数 (あるいは現在の引数の残りの部分) を取り出し、正しい型の値か確かめ、指定した保存先に保存するよう optparse に指示します。

例えば:

parser.add_option("-f", "--file",
                  action="store", type="string", dest="filename")

例えば、以下のように指定しておき、偽のコマンドラインを作成して optparse に解析させてみましょう:

args = ["-f", "foo.txt"]
(options, args) = parser.parse_args(args)

オプション文字列 -f を見つけると、 optparse は次の引数である foo.txt を消費し、その値を options.filename に保存します。従って、この parse_args() 呼び出し後には options.filename"foo.txt" になっています。

オプションの型として、 optparse は他にも intfloat をサポートしています:

parser.add_option("-n", type="int", dest="num")

このオプションには長い形式のオプション文字列がないため、設定に問題がないということに注意してください。また、デフォルトのアクションは store なので、ここでは action を明示的に指定していません。

架空のコマンドラインをもう一つ解析してみましょう。今度は、オプション引数をオプションの右側にぴったりくっつけて一緒くたにします: -n42 (一つの引数のみ) は -n 42 (二つの引数からなる) と等価になるので

(options, args) = parser.parse_args(["-n42"])
print(options.num)

42 を出力します。

型を指定しない場合、 optparse は引数を string であると仮定します。デフォルトのアクションが store であることも併せて考えると、最初の例はもっと短くなります:

parser.add_option("-f", "--file", dest="filename")

保存先 (destination) を指定しない場合、 optparse はデフォルト値としてオプション文字列から気のきいた名前を設定します: 最初に指定した長い形式のオプション文字列が --foo-bar であれば、デフォルトの保存先は foo_bar になります。長い形式のオプション文字列がなければ、 optparse は最初に指定した短い形式のオプション文字列を探します: 例えば、 -f に対する保存先は f になります。

optparse にはビルトインの complex 型も含まれています。型の追加については optparse の拡張 で触れています。

36.1.2.3. ブール値 (フラグ) オプションの処理

フラグオプション—特定のオプションに対して真または偽の値の値を設定するオプション— はよく使われます。 optparse では、二つのアクション、 store_true および store_false をサポートしています。例えば、 verbose というフラグを -v で有効にして、 -q で無効にしたいとします:

parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose")

ここでは二つのオプションに同じ保存先を指定していますが、全く問題ありません (下記のように、デフォルト値の設定を少し注意深く行わなければならないだけです)

-v をコマンドライン上に見つけると、 optparseoptions.verboseTrue に設定します。 -q を見つければ、 options.verboseFalse にセットされます。

36.1.2.4. その他のアクション

この他にも、 optparse は以下のようなアクションをサポートしています:

"store_const"

定数値を保存します

"append"

オプションの引数を指定のリストに追加します

"count"

指定のカウンタを 1 増やします

"callback"

指定の関数を呼び出します

これらのアクションについては、 リファレンスガイド 節の「リファレンスガイド」および オプション処理コールバック 節で触れます。

36.1.2.5. デフォルト値

上記の例は全て、何らかのコマンドラインオプションが見つかった時に何らかの変数 (保存先: destination) に値を設定していました。では、該当するオプションが見つからなかった場合には何が起きるのでしょうか?デフォルトは全く与えていないため、これらの値は全て None になります。たいていはこれで十分ですが、もっときちんと制御したい場合もあります。 optparse では各保存先に対してデフォルト値を指定し、コマンドラインの解析前にデフォルト値が設定されるようにできます。

まず、 verbose/quiet の例について考えてみましょう。 optparse に対して、 -q がない限り verboseTrue に設定させたいなら、以下のようにします:

parser.add_option("-v", action="store_true", dest="verbose", default=True)
parser.add_option("-q", action="store_false", dest="verbose")

デフォルトの値は特定のオプションではなく 保存先 に対して適用されます。また、これら二つのオプションはたまたま同じ保存先を持っているにすぎないため、上のコードは下のコードと全く等価になります:

parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose", default=True)

下のような場合を考えてみましょう:

parser.add_option("-v", action="store_true", dest="verbose", default=False)
parser.add_option("-q", action="store_false", dest="verbose", default=True)

やはり verbose のデフォルト値は True になります; 特定の目的変数に対するデフォルト値として有効なのは、最後に指定した値だからです。

デフォルト値をすっきりと指定するには、 OptionParserset_defaults() メソッドを使います。このメソッドは parse_args() を呼び出す前ならいつでも使えます:

parser.set_defaults(verbose=True)
parser.add_option(...)
(options, args) = parser.parse_args()

前の例と同様、あるオプションの値の保存先に対するデフォルトの値は最後に指定した値になります。コードを読みやすくするため、デフォルト値を設定するときには両方のやり方を混ぜるのではなく、片方だけを使うようにしましょう。

36.1.2.6. ヘルプの生成

optparse にはヘルプと使い方の説明 (usage text) を生成する機能があり、ユーザに優しいコマンドラインインタフェースを作成する上で役立ちます。やらなければならないのは、各オプションに対する help の値と、必要ならプログラム全体の使用法を説明する短いメッセージを与えることだけです。ユーザフレンドリな (ドキュメント付きの) オプションを追加した OptionParser を以下に示します:

usage = "usage: %prog [options] arg1 arg2"
parser = OptionParser(usage=usage)
parser.add_option("-v", "--verbose",
                  action="store_true", dest="verbose", default=True,
                  help="make lots of noise [default]")
parser.add_option("-q", "--quiet",
                  action="store_false", dest="verbose",
                  help="be vewwy quiet (I'm hunting wabbits)")
parser.add_option("-f", "--filename",
                  metavar="FILE", help="write output to FILE")
parser.add_option("-m", "--mode",
                  default="intermediate",
                  help="interaction mode: novice, intermediate, "
                       "or expert [default: %default]")

optparse がコマンドライン上で -h--help を見つけた場合や、 parser.print_help() を呼び出した場合、この OptionParser は以下のようなメッセージを標準出力に出力します:

Usage: <yourscript> [options] arg1 arg2

Options:
  -h, --help            show this help message and exit
  -v, --verbose         make lots of noise [default]
  -q, --quiet           be vewwy quiet (I'm hunting wabbits)
  -f FILE, --filename=FILE
                        write output to FILE
  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or
                        expert [default: intermediate]

(help オプションでヘルプを出力した場合、 optparse は出力後にプログラムを終了します。)

optparse ができるだけうまくメッセージを生成するよう手助けするには、他にもまだまだやるべきことがあります:

  • スクリプト自体の利用法を表すメッセージを定義します:

    usage = "usage: %prog [options] arg1 arg2"
    

    optparse%prog を現在のプログラム名、すなわち os.path.basename(sys.argv[0]) と置き換えます。この文字列は詳細なオプションヘルプの前に展開され出力されます。

    usage の文字列を指定しない場合、 optparse は型どおりとはいえ気の利いたデフォルト値、 "Usage: %prog [options]" を使います。固定引数をとらないスクリプトの場合はこれで十分でしょう。

  • 全てのオプションにヘルプ文字列を定義します。行の折り返しは気にしなくてかまいません — optparse は行の折り返しに気を配り、見栄えのよいヘルプ出力を生成します。

  • オプションが値をとるということは自動的に生成されるヘルプメッセージの中で分かります。例えば、”mode” option の場合にはこのようになります:

    -m MODE, --mode=MODE
    

    ここで “MODE” はメタ変数 (meta-variable) と呼ばれます: メタ変数は、ユーザが -m/--mode に対して指定するはずの引数を表します。デフォルトでは、 optparse は保存先の変数名を大文字だけにしたものをメタ変数に使います。これは時として期待通りの結果になりません — 例えば、上の例の --filename オプションでは明示的に metavar="FILE" を設定しており、その結果自動生成されたオプション説明テキストは:

    -f FILE, --filename=FILE
    

    この機能の重要さは、単に表示スペースを節約するといった理由にとどまりません: 上の例では、手作業で書いたヘルプテキストの中でメタ変数として FILE を使っています。その結果、ユーザに対してやや堅苦しい表現の書法 -f FILE と、より平易に意味付けを説明した “write output to FILE” との間に対応があるというヒントを与えています。これは、エンドユーザにとってより明解で便利なヘルプテキストを作成する単純でありながら効果的な手法なのです。

  • デフォルト値を持つオプションはヘルプ文字列に %default を含むことができます—optparse はそれをオプションのデフォルト値に str() を適用したもので置き換えます。オプションがデフォルト値を持たない (もしくはデフォルト値が None である) 場合、 %defaultnone に展開されます。

36.1.2.6.1. オプションをグループ化する

たくさんのオプションを扱う場合、オプションをグループ分けするとヘルプ出力が見やすくなります。 OptionParser は、複数のオプションをまとめたオプショングループを複数持つことができます。

オプションのグループは、 OptionGroup を使って作成します:

class optparse.OptionGroup(parser, title, description=None)

where

  • parser は、このグループが属する OptionParser のインスタンスです

  • title はグループのタイトルです

  • description はオプションで、グループの長い説明です

OptionGroup は (OptionParser のように) OptionContainer を継承していて、オプションをグループに追加するために add_option() メソッドを利用できます。

全てのオプションを定義したら、 OptionParseradd_option_group() メソッドを使ってグループを定義済みのパーサーに追加します。

前のセクションで定義したパーサーに、続けて OptionGroup を追加します:

group = OptionGroup(parser, "Dangerous Options",
                    "Caution: use these options at your own risk.  "
                    "It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)

この結果のヘルプ出力は次のようになります:

Usage: <yourscript> [options] arg1 arg2

Options:
  -h, --help            show this help message and exit
  -v, --verbose         make lots of noise [default]
  -q, --quiet           be vewwy quiet (I'm hunting wabbits)
  -f FILE, --filename=FILE
                        write output to FILE
  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or
                        expert [default: intermediate]

  Dangerous Options:
    Caution: use these options at your own risk.  It is believed that some
    of them bite.

    -g                  Group option.

さらにサンプルを拡張して、複数のグループを使うようにしてみます:

group = OptionGroup(parser, "Dangerous Options",
                    "Caution: use these options at your own risk.  "
                    "It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)

group = OptionGroup(parser, "Debug Options")
group.add_option("-d", "--debug", action="store_true",
                 help="Print debug information")
group.add_option("-s", "--sql", action="store_true",
                 help="Print all SQL statements executed")
group.add_option("-e", action="store_true", help="Print every action done")
parser.add_option_group(group)

出力結果は次のようになります:

Usage: <yourscript> [options] arg1 arg2

Options:
  -h, --help            show this help message and exit
  -v, --verbose         make lots of noise [default]
  -q, --quiet           be vewwy quiet (I'm hunting wabbits)
  -f FILE, --filename=FILE
                        write output to FILE
  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or expert
                        [default: intermediate]

  Dangerous Options:
    Caution: use these options at your own risk.  It is believed that some
    of them bite.

    -g                  Group option.

  Debug Options:
    -d, --debug         Print debug information
    -s, --sql           Print all SQL statements executed
    -e                  Print every action done

もう1つの、特にオプショングループをプログラムから操作するときに利用できるメソッドがあります:

OptionParser.get_option_group(opt_str)

短いオプション文字列もしくは長いオプション文字列 opt_str (例。 '-o''--option') が属する OptionGroup を返します。そのような OptionGroup が無い場合は、 None を返します。

36.1.2.7. バージョン番号の出力

optparse では、使用法メッセージと同様にプログラムのバージョン文字列を出力できます。 OptionParserversion 引数に文字列を渡します:

parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")

%progusage と同じような展開を受けます。その他にも version には何でも好きな内容を入れられます。 version を指定した場合、 optparse は自動的に --version オプションをパーザに渡します。コマンドライン中に --version が見つかると、 optparseversion 文字列を展開して (%prog を置き換えて) 標準出力に出力し、プログラムを終了します。

例えば、/usr/bin/foo という名前のスクリプトなら:

$ /usr/bin/foo --version
foo 1.0

以下の2つのメソッドを、version 文字列を表示するために利用できます:

OptionParser.print_version(file=None)

現在のプログラムのバージョン (self.version) を file (デフォルト: stdout) へ表示します。 print_usage() と同じく、 self.version の中の全ての %prog が現在のプログラム名に置き換えられます。 self.version が空文字列だだったり未定義だったときは何もしません。

OptionParser.get_version()

print_version() と同じですが、バージョン文字列を表示する代わりに返します。

36.1.2.8. optparse のエラー処理法

optparse を使う場合に気を付けなければならないエラーには、大きく分けてプログラマ側のエラーとユーザ側のエラーという二つの種類があります。プログラマ側のエラーの多くは、例えば不正なオプション文字列や定義されていないオプション属性の指定、あるいはオプション属性を指定し忘れるといった、誤った OptionParser.add_option(), 呼び出しによるものです。こうした誤りは通常通りに処理されます。すなわち、例外(optparse.OptionErrorTypeError) を送出して、プログラムをクラッシュさせます。

もっと重要なのはユーザ側のエラーの処理です。というのも、ユーザの操作エラーというものはコードの安定性に関係なく起こるからです。 optparse は、誤ったオプション引数の指定 (整数を引数にとるオプション -n に対して -n 4x と指定してしまうなど) や、引数を指定し忘れた場合 (-n が何らかの引数をとるオプションであるのに、 -n が引数の末尾に来ている場合) といった、ユーザによるエラーを自動的に検出します。また、アプリケーション側で定義されたエラー条件が起きた場合、 OptionParser.error() を呼び出してエラーを通知できます:

(options, args) = parser.parse_args()
...
if options.a and options.b:
    parser.error("options -a and -b are mutually exclusive")

いずれの場合にも optparse はエラーを同じやり方で処理します。すなわち、プログラムの使用法メッセージとエラーメッセージを標準エラー出力に出力して、終了ステータス 2 でプログラムを終了させます。

上に挙げた最初の例、すなわち整数を引数にとるオプションにユーザが 4x を指定した場合を考えてみましょう:

$ /usr/bin/foo -n 4x
Usage: foo [options]

foo: error: option -n: invalid integer value: '4x'

値を全く指定しない場合には、以下のようになります:

$ /usr/bin/foo -n
Usage: foo [options]

foo: error: -n option requires an argument

optparse は、常にエラーを引き起こしたオプションについて説明の入ったエラーメッセージを生成するよう気を配ります; 従って、 OptionParser.error() をアプリケーションコードから呼び出す場合にも、同じようなメッセージになるようにしてください。

optparse のデフォルトのエラー処理動作が気に入らないのなら、 OptionParser をサブクラス化して、 exit() かつ/または error() をオーバライドする必要があります。

36.1.2.9. 全てをつなぎ合わせる

optparse を使ったスクリプトは、通常以下のようになります:

from optparse import OptionParser
...
def main():
    usage = "usage: %prog [options] arg"
    parser = OptionParser(usage)
    parser.add_option("-f", "--file", dest="filename",
                      help="read data from FILENAME")
    parser.add_option("-v", "--verbose",
                      action="store_true", dest="verbose")
    parser.add_option("-q", "--quiet",
                      action="store_false", dest="verbose")
    ...
    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error("incorrect number of arguments")
    if options.verbose:
        print("reading %s..." % options.filename)
    ...

if __name__ == "__main__":
    main()

36.1.3. リファレンスガイド

36.1.3.1. parserを作る

optparse を使う最初の一歩は OptionParser インスタンスを作ることです。

class optparse.OptionParser(...)

OptionParser のコンストラクタの引数はどれも必須ではありませんが、いくつものキーワード引数がオプションとして使えます。これらはキーワード引数として渡さなければなりません。すなわち、引数が宣言されている順番に頼ってはいけません。

usage (デフォルト: "%prog [options]")

プログラムが間違った方法で実行されるかまたはヘルプオプションを付けて実行された場合に表示される使用法です。 optparse は使用法の文字列を表示する際に %progos.path.basename(sys.argv[0]) (または prog キーワード引数が指定されていればその値) に展開します。使用法メッセージを抑制するためには特別な optparse.SUPPRESS_USAGE という値を指定します。

option_list (デフォルト: [])

パーザに追加する Option オブジェクトのリストです。 option_list の中のオプションは standard_option_list (OptionParser のサブクラスでセットされる可能性のあるクラス属性) の後に追加されますが、バージョンやヘルプのオプションよりは前になります。このオプションの使用は推奨されません。パーザを作成した後で、 add_option() を使って追加してください。

option_class (デフォルト: optparse.Option)

add_option() でパーザにオプションを追加するときに使用されるクラス。

version (デフォルト: None)

ユーザがバージョンオプションを与えたときに表示されるバージョン文字列です。 version に真の値を与えると、 optparse は自動的に単独のオプション文字列 --version とともにバージョンオプションを追加します。部分文字列 %progusage と同様に展開されます。

conflict_handler (デフォルト: "error")

オプション文字列が衝突するようなオプションがパーザに追加されたときにどうするかを指定します。 オプション間の衝突 節を参照して下さい。

description (デフォルト: None)

プログラムの概要を表す一段落のテキストです。 optparse はユーザがヘルプを要求したときにこの概要を現在のターミナルの幅に合わせて整形し直して表示します (usage の後、オプションリストの前に表示されます)。

formatter (デフォルト: 新しい IndentedHelpFormatter)

ヘルプテキストを表示する際に使われる optparse.HelpFormatter のインスタンスです。 optparse はこの目的のためにすぐ使えるクラスを二つ提供しています。 IndentedHelpFormatter と TitledHelpFormatter がそれです。

add_help_option (デフォルト: True)

もし真ならば、 optparse はパーザにヘルプオプションを (オプション文字列 -h--help とともに)追加します。

prog

usageversion の中の %prog を展開するときに os.path.basename(sys.argv[0]) の代わりに使われる文字列です。

epilog (デフォルト: None)

オプションのヘルプの後に表示されるヘルプテキスト.

36.1.3.2. パーザへのオプション追加

パーザにオプションを加えていくにはいくつか方法があります。推奨するのは チュートリアル 節で示したような OptionParser.add_option() を使う方法です。 add_option() は以下の二つのうちいずれかの方法で呼び出せます:

  • (make_option() などが返す) Option インスタンスを渡します

  • make_option() に (すなわち Option のコンストラクタに) 固定引数とキーワード引数の組み合わせを渡して、 Option インスタンスを生成させます

もう一つの方法は、あらかじめ作成しておいた Option インスタンスからなるリストを、以下のようにして OptionParser のコンストラクタに渡すというものです:

option_list = [
    make_option("-f", "--filename",
                action="store", type="string", dest="filename"),
    make_option("-q", "--quiet",
                action="store_false", dest="verbose"),
    ]
parser = OptionParser(option_list=option_list)

(make_option()Option インスタンスを生成するファクトリ関数です; 現在のところ、この関数は Option のコンストラクタの別名にすぎません。 optparse の将来のバージョンでは、 Option を複数のクラスに分割し、 make_option() は適切なクラスを選んでインスタンスを生成するようになる予定です。従って、 Option を直接インスタンス化しないでください。)

36.1.3.3. オプションの定義

各々の Option インスタンス、は -f--file といった同義のコマンドラインオプションからなる集合を表現しています。一つの Option には任意の数のオプションを短い形式でも長い形式でも指定できます。ただし、少なくとも一つは指定しなければなりません。

正しい方法で Option インスタンスを生成するには、 OptionParseradd_option() を使います。

OptionParser.add_option(option)
OptionParser.add_option(*opt_str, attr=value, ...)

短い形式のオプション文字列を一つだけ持つようなオプションを生成するには次のようにします:

parser.add_option("-f", attr=value, ...)

また、長い形式のオプション文字列を一つだけ持つようなオプションの定義は次のようになります:

parser.add_option("--foo", attr=value, ...)

キーワード引数は新しい Option オブジェクトの属性を定義します。オプションの属性のうちでもっとも重要なのは action です。この属性は、他のどの属性と関連があるか、そしてどの属性が必要かに大きく作用します。関係のないオプション属性を指定したり、必要な属性を指定し忘れたりすると、 optparse は誤りを解説した OptionError 例外を送出します。

コマンドライン上にあるオプションが見つかったときの optparse の振舞いを決定しているのは アクション(action) です。 optparse でハードコードされている標準的なアクションには以下のようなものがあります:

"store"

オプションの引数を保存します (デフォルトの動作です)

"store_const"

定数値を保存します

"store_true"

真 (True) を保存します

"store_false"

偽 (False) を保存します

"append"

オプションの引数を指定のリストに追加します

"append_const"

オプションの引数をリストに追加します

"count"

指定のカウンタを 1 増やします

"callback"

指定の関数を呼び出します

"help"

全てのオプションとそのドキュメントの入った使用法メッセージを出力します

(アクションを指定しない場合、デフォルトは "store" になります。このアクションでは、 type および dest オプション属性を指定できます。 標準的なオプション・アクション を参照してください。)

すでにお分かりのように、ほとんどのアクションはどこかに値を保存したり、値を更新したりします。この目的のために、 optparse は常に特別なオブジェクトを作り出し、それは通常 options と呼ばれます (optparse.Values のインスタンスになっています)。オプションの引数 (や、その他の様々な値) は、 dest (保存先: destination) オプション属性に従って、 options の属性として保存されます。

例えばこれを呼び出した場合

parser.parse_args()

optparse はまず options オブジェクトを生成します:

options = Values()

パーザ中で以下のようなオプションが定義されていて

parser.add_option("-f", "--file", action="store", type="string", dest="filename")

パーズしたコマンドラインに以下のいずれかが入っていた場合:

-ffoo
-f foo
--file=foo
--file foo

optparse はこのオプションを見つけて、以下と同等の処理を行います

options.filename = "foo"

type および dest オプション属性は action と同じくらい重要ですが、 全ての オプションで意味をなすのは action だけなのです。

36.1.3.4. オプション属性

以下のオプション属性は OptionParser.add_option() へのキーワード引数として渡すことができます。特定のオプションに無関係なオプション属性を渡した場合、または必須のオプションを渡しそこなった場合、 optparseOptionError を送出します。

Option.action

(デフォルト: "store")

このオプションがコマンドラインにあった場合に optparse に何をさせるかを決めます。取りうるオプションについては こちら を参照してください。

Option.type

(デフォルト: "string")

このオプションに与えられる引数の型 (たとえば "string""int") です。取りうるオプションについては こちら を参照してください。

Option.dest

(デフォルト: オプション文字列を使う)

このオプションのアクションがある値をどこかに書いたり書き換えたりを意味する場合、これは optparse にその書く場所を教えます。詳しく言えば dest には optparse がコマンドラインを解析しながら組み立てる options オブジェクトの属性の名前を指定します。

Option.default

コマンドラインに指定がなかったときにこのオプションの対象に使われる値です。 OptionParser.set_defaults() も参照してください。

Option.nargs

(デフォルト: 1)

このオプションがあったときに幾つの type 型の引数が消費されるべきかを指定します。 1 より大きい場合、 optparsedest に値のタプルを格納します。

Option.const

定数を格納する動作のための、その定数です。

Option.choices

"choice" 型オプションに対してユーザが選べる選択肢となる文字列のリストです。

Option.callback

アクションが "callback" であるオプションに対し、このオプションがあったときに呼ばれる呼び出し可能オブジェクトです。呼び出し時に渡される引数の詳細については、 オプション処理コールバック を参照してください。

Option.callback_args
Option.callback_kwargs

callback に渡される標準的な4つのコールバック引数の後ろに追加する、位置指定引数とキーワード引数。

Option.help

ユーザが help オプション(--help のような)を指定したときに表示される、使用可能な全オプションのリストの中のこのオプションに関する説明文です。説明文を提供しておかなければ、オプションは説明文なしで表示されます。オプションを隠すには特殊な値 optparse.SUPPRESS_HELP を使います。

Option.metavar

(デフォルト: オプション文字列を使う)

説明文を表示する際にオプションの引数の身代わりになるものです。例は チュートリアル 節を参照してください。

36.1.3.5. 標準的なオプション・アクション

様々なオプション・アクションにはどれも互いに少しづつ異なった条件と作用があります。ほとんどのアクションに関連するオプション属性がいくつかあり、値を指定して optparse の挙動を操作できます。いくつかのアクションには必須の属性があり、必ず値を指定しなければなりません。

  • "store" [関連: type, dest, nargs, choices]

    オプションの後には必ず引数が続きます。引数は type に従って値に変換されて dest に保存されます。 nargs > 1 の場合、複数の引数をコマンドラインから取り出します。引数は全て type に従って変換され、 dest にタプルとして保存されます。 標準のオプション型 節を参照してください。

    choices を(文字列のリストかタプルで) 指定した場合、型のデフォルト値は "choice" になります。

    type を指定しない場合、デフォルトの値は "string" です。

    dest を指定しない場合、 optparse は保存先を最初の長い形式のオプション文字列から導出します (例えば、 --foo-barfoo_bar になります)。長い形式のオプション文字列がない場合、 optparse は最初の短い形式のオプションから保存先の変数名を導出します (-ff になります)。

    parser.add_option("-f")
    parser.add_option("-p", type="float", nargs=3, dest="point")
    

    とすると、以下のようなコマンドライン

    -f foo.txt -p 1 -3.5 4 -fbar.txt
    

    を解析した場合、 optparse は以下のように設定を行います

    options.f = "foo.txt"
    options.point = (1.0, -3.5, 4.0)
    options.f = "bar.txt"
    
  • "store_const" [関連: const; 関連: dest]

    constdest に保存します。

    parser.add_option("-q", "--quiet",
                      action="store_const", const=0, dest="verbose")
    parser.add_option("-v", "--verbose",
                      action="store_const", const=1, dest="verbose")
    parser.add_option("--noisy",
                      action="store_const", const=2, dest="verbose")
    

    とします。 --noisy が見つかると、 optparse

    options.verbose = 2
    
  • "store_true" [関連: dest]

    "store_const" の特殊なケースで、真 (True) を dest に保存します。

  • "store_false" [関連: dest]

    "store_true" と似ていて、偽 (False) を保存します。

    parser.add_option("--clobber", action="store_true", dest="clobber")
    parser.add_option("--no-clobber", action="store_false", dest="clobber")
    
  • "append" [関連: type, dest, nargs, choices]

    このオプションの後ろには必ず引数が続きます。引数は dest のリストに追加されます。 dest のデフォルト値を指定しなかった場合、 optparse がこのオプションを最初にみつけた時点で空のリストを自動的に生成します。 nargs > 1 の場合、複数の引数をコマンドラインから取り出し、長さ nargs のタプルを生成して dest に追加します。

    type および dest のデフォルト値は "store" アクションと同じです。

    parser.add_option("-t", "--tracks", action="append", type="int")
    

    -t3 がコマンドライン上で見つかると、 optparse は:

    options.tracks = []
    options.tracks.append(int("3"))
    

    その後、--tracks=4 が見つかると以下を実行します:

    options.tracks.append(int("4"))
    

    append アクションは、オプションの現在の値の append メソッドを呼び出します。これは、どのデフォルト値も append メソッドを持っていなければならないことを意味します。また、デフォルト値が空でない場合、オプションの解析結果は、そのデフォルトの要素の後ろにコマンドラインからの値が追加されたものになる、ということも意味します:

    >>> parser.add_option("--files", action="append", default=['~/.mypkg/defaults'])
    >>> opts, args = parser.parse_args(['--files', 'overrides.mypkg'])
    >>> opts.files
    ['~/.mypkg/defaults', 'overrides.mypkg']
    
  • "append_const" [関連: const; 関連: dest]

    "store_const" と同様ですが、 const の値は dest に追加(append)されます。 "append" の場合と同じように dest のデフォルトは None ですがこのオプションを最初にみつけた時点で空のリストを自動的に生成します。

  • "count" [関連: dest]

    dest に保存されている整数値をインクリメントします。 dest は (デフォルトの値を指定しない限り) 最初にインクリメントを行う前にゼロに設定されます。

    parser.add_option("-v", action="count", dest="verbosity")
    

    コマンドライン上で最初に -v が見つかると、 optparse は:

    options.verbosity = 0
    options.verbosity += 1
    

    以後、-v が見つかるたびに

    options.verbosity += 1
    
  • "callback" [必須: callback; 関連: type, nargs, callback_args, callback_kwargs]

    callback に指定された関数を次のように呼び出します

    func(option, opt_str, value, parser, *args, **kwargs)
    

    詳細は、 オプション処理コールバック 節を参照してください。

  • "help"

    現在のオプションパーザ内の全てのオプションに対する完全なヘルプメッセージを出力します。ヘルプメッセージは OptionParser のコンストラクタに渡した usage 文字列と、各オプションに渡した help 文字列から生成します。

    オプションに help 文字列が指定されていなくても、オプションはヘルプメッセージ中に列挙されます。オプションを完全に表示させないようにするには、特殊な値 optparse.SUPPRESS_HELP を使ってください。

    optparse は全ての OptionParser に自動的に help オプションを追加するので、通常自分で生成する必要はありません。

    from optparse import OptionParser, SUPPRESS_HELP
    
    # usually, a help option is added automatically, but that can
    # be suppressed using the add_help_option argument
    parser = OptionParser(add_help_option=False)
    
    parser.add_option("-h", "--help", action="help")
    parser.add_option("-v", action="store_true", dest="verbose",
                      help="Be moderately verbose")
    parser.add_option("--file", dest="filename",
                      help="Input file to read data from")
    parser.add_option("--secret", help=SUPPRESS_HELP)
    

    optparse がコマンドライン上に -h または --help を見つけると、以下のようなヘルプメッセージを標準出力に出力します (sys.argv[0]"foo.py" だとします):

    Usage: foo.py [options]
    
    Options:
      -h, --help        Show this help message and exit
      -v                Be moderately verbose
      --file=FILENAME   Input file to read data from
    

    ヘルプメッセージの出力後、 optparsesys.exit(0) でプロセスを終了します。

  • "version"

    OptionParser に指定されているバージョン番号を標準出力に出力して終了します。バージョン番号は、実際には OptionParserprint_version() メソッドで書式化されてから出力されます。通常、 OptionParser のコンストラクタに version 引数が指定されたときのみ関係のあるアクションです。 help オプションと同様、 optparse はこのオプションを必要に応じて自動的に追加するので、 version オプションを作成することはほとんどないでしょう。

36.1.3.6. 標準のオプション型

optparse には、 "string", "int", "choice", "float", "complex" の 5 種類のビルトインのオプション型があります。 新たなオプションの型を追加したければ、 optparse の拡張 節を参照してください。

文字列オプションの引数はチェックや変換を一切受けません: コマンドライン上のテキストは保存先にそのまま保存されます (またはコールバックに渡されます)。

整数引数 ("int" 型) は次のように解析されます:

  • 数が 0x から始まるならば、16進数として読み取られます

  • 数が 0 から始まるならば、8進数として読み取られます

  • 数が 0b から始まるならば、2進数として読み取られます

  • それ以外の場合、数は10進数として読み取られます

変換は適切な底 (2, 8, 10, 16 のどれか) とともに int() を呼び出すことで行なわれます。この変換が失敗した場合 optparse の処理も失敗に終わりますが、 より役に立つエラーメッセージを出力します。

"float" および "complex" のオプション引数は直接 float()complex() で変換されます。エラーは同様の扱いです。

"choice" オプションは "string" オプションのサブタイプです。 choices オプションの属性 (文字列からなるシーケンス) には、利用できるオプション引数のセットを指定します。 optparse.check_choice() はユーザの指定したオプション引数とマスタリストを比較して、無効な文字列が指定された場合には OptionValueError を送出します。

36.1.3.7. 引数を解析する

OptionParser を作成してオプションを追加していく上で大事なポイントは、 parse_args() メソッドの呼び出しです:

(options, args) = parser.parse_args(args=None, values=None)

ここで入力パラメータは

args

処理する引数のリスト (デフォルト: sys.argv[1:])

values

オプション引数を格納する optparse.Values のオブジェクト (デフォルト: 新しい Values のインスタンス) – 既存のオブジェクトを指定した場合、オプションのデフォルトは初期化されません

であり、戻り値は

options

values に渡されたものと同じオブジェクト、または optparse によって生成された optparse.Values インスタンス

args

全てのオプションの処理が終わった後で残った固定引数

一番普通の使い方は一切キーワード引数を使わないというものです。 values を指定した場合、それは繰り返される setattr() の呼び出し (大雑把に言うと保存される各オプション引数につき一回ずつ) で更新されていき、 parse_args() で返されます。

parse_args() が引数リストでエラーに遭遇した場合、 OptionParser の error() メソッドを適切なエンドユーザ向けのエラーメッセージとともに呼び出します。この呼び出しにより、最終的に終了ステータス 2 (伝統的な Unix におけるコマンドラインエラーの終了ステータス) でプロセスを終了させることになります。

36.1.3.8. オプション解析器への問い合わせと操作

オプションパーザのデフォルトの振る舞いは、ある程度カスタマイズすることができます。また、オプションパーザの中を調べることもできます。OptionParser は幾つかのヘルパーメソッドを提供しています:

OptionParser.disable_interspersed_args()

オプションで無い最初の引数を見つけた時点でパースを止めるように設定します。例えば、 -a-b が両方とも引数を取らないシンプルなオプションだったとすると、 optparse は通常次の構文を受け付け:

prog -a arg1 -b arg2

それを次と同じように扱います

prog -a -b arg1 arg2

この機能を無効にしたいときは、 disable_interspersed_args() メソッドを呼び出してください。古典的な Unix システムのように、最初のオプションでない引数を見つけたときにオプションの解析を止めるようになります。

別のコマンドを実行するコマンドをプロセッサを作成する際、別のコマンドのオプションと自身のオプションが混ざるのを防ぐために利用することができます。例えば、各コマンドがそれぞれ異なるオプションのセットを持つ場合などに有効です。

OptionParser.enable_interspersed_args()

オプションで無い最初の引数を見つけてもパースを止めないように設定します。オプションとコマンド引数の順序が混ざっても良いようになります。これはデフォルトの動作です。

OptionParser.get_option(opt_str)

オプション文字列 opt_str に対する Option インスタンスを返します。該当するオプションがなければ None を返します。

OptionParser.has_option(opt_str)

OptionParser に(-q--verbose のような) オプション opt_str がある場合、真を返します。

OptionParser.remove_option(opt_str)

OptionParseropt_str に対応するオプションがある場合、そのオプションを削除します。該当するオプションに他のオプション文字列が指定されていた場合、それらのオプション文字列は全て無効になります。 opt_str がこの OptionParser オブジェクトのどのオプションにも属さない場合、 ValueError を送出します。

36.1.3.9. オプション間の衝突

注意が足りないと、衝突するオプションを定義してしまうことがあります:

parser.add_option("-n", "--dry-run", ...)
...
parser.add_option("-n", "--noisy", ...)

(とりわけ、OptionParser から標準的なオプションを備えた自前のサブクラスを定義してしまった場合にはよく起きます。)

ユーザがオプションを追加するたびに、 optparse は既存のオプションとの衝突がないかチェックします。何らかの衝突が見付かると、現在設定されている衝突処理メカニズムを呼び出します。衝突処理メカニズムはコンストラクタ中で呼び出せます:

parser = OptionParser(..., conflict_handler=handler)

個別にも呼び出せます:

parser.set_conflict_handler(handler)

衝突時の処理をおこなうハンドラ(handler)には、以下のものが利用できます:

"error" (デフォルト)

オプション間の衝突をプログラム上のエラーとみなし、 OptionConflictError を送出します

"resolve"

オプション間の衝突をインテリジェントに解決します (下記参照)

一例として、衝突をインテリジェントに解決する OptionParser を定義し、衝突を起こすようなオプションを追加してみましょう:

parser = OptionParser(conflict_handler="resolve")
parser.add_option("-n", "--dry-run", ..., help="do no harm")
parser.add_option("-n", "--noisy", ..., help="be noisy")

この時点で、 optparse はすでに追加済のオプションがオプション文字列 -n を使っていることを検出します。 conflict_handler"resolve" なので、 optparse は既に追加済のオプションリストの方から -n を除去して問題を解決します。従って、 -n の除去されたオプションは --dry-run だけでしか有効にできなくなります。ユーザがヘルプ文字列を要求した場合、問題解決の結果を反映したメッセージが出力されます:

Options:
  --dry-run     do no harm
  ...
  -n, --noisy   be noisy

これまでに追加したオプション文字列を跡形もなく削り去り、ユーザがそのオプションをコマンドラインから起動する手段をなくせます。この場合、 optparse はオプションを完全に除去してしまうので、こうしたオプションはヘルプテキストやその他のどこにも表示されなくなります。例えば、現在の OptionParser の場合、以下の操作:

parser.add_option("--dry-run", ..., help="new dry-run option")

を行った時点で、最初の -n/--dry-run オプションはもはやアクセスできなくなります。このため、 optparse はオプションを消去してしまい、ヘルプテキストだけが残ります:

Options:
  ...
  -n, --noisy   be noisy
  --dry-run     new dry-run option

36.1.3.10. クリーンアップ

OptionParser インスタンスはいくつかの循環参照を抱えています。このことは Python のガーベジコレクタにとって問題になるわけではありませんが、使い終わった OptionParser に対して destroy() を呼び出すことでこの循環参照を意図的に断ち切るという方法を選ぶこともできます。この方法は特に長時間実行するアプリケーションで OptionParser から大きなオブジェクトグラフが到達可能になっているような場合に有用です。

36.1.3.11. その他のメソッド

OptionParser にはその他にも幾つかの公開されたメソッドがあります:

OptionParser.set_usage(usage)

上で説明したコンストラクタの usage キーワード引数での規則に従った使用法の文字列をセットします。 None を渡すとデフォルトの使用法文字列が使われるようになり、 optparse.SUPPRESS_USAGE によって使用法メッセージを抑制できます。

OptionParser.print_usage(file=None)

現在のプログラムの使用法メッセージ (self.usage) を file (デフォルト: stdout) に表示します。self.usage 内にある全ての %prog という文字列は現在のプログラム名に置換されます。self.usage が空もしくは未定義の時は何もしません。

OptionParser.get_usage()

print_usage() と同じですが、使用法メッセージを表示する代わりに文字列として返します。

OptionParser.set_defaults(dest=value, ...)

幾つかの保存先に対してデフォルト値をまとめてセットします。 set_defaults() を使うのは複数のオプションにデフォルト値をセットする好ましいやり方です。複数のオプションが同じ保存先を共有することがあり得るからです。たとえば幾つかの “mode” オプションが全て同じ保存先をセットするものだったとすると、どのオプションもデフォルトをセットすることができ、しかし最後に指定したものだけが有効になります:

parser.add_option("--advanced", action="store_const",
                  dest="mode", const="advanced",
                  default="novice")    # overridden below
parser.add_option("--novice", action="store_const",
                  dest="mode", const="novice",
                  default="advanced")  # overrides above setting

こうした混乱を避けるために set_defaults() を使います:

parser.set_defaults(mode="advanced")
parser.add_option("--advanced", action="store_const",
                  dest="mode", const="advanced")
parser.add_option("--novice", action="store_const",
                  dest="mode", const="novice")

36.1.4. オプション処理コールバック

optparse の組み込みのアクションや型が望みにかなったものでない場合、二つの選択肢があります: 一つは optparse の拡張、もう一つは callback オプションの定義です。 optparse の拡張は汎用性に富んでいますが、単純なケースに対していささか大げさでもあります。大体は簡単なコールバックで事足りるでしょう。

callback オプションの定義は二つのステップからなります:

  • "callback" アクションを使ってオプション自体を定義する

  • コールバックを書く。コールバックは少なくとも後で説明する 4 つの引数をとる関数 (またはメソッド) でなければなりません

36.1.4.1. callbackオプションの定義

callback オプションを最も簡単に定義するには、 OptionParser.add_option() メソッドを使います。 action の他に指定しなければならない属性は callback すなわちコールバックする関数自体です:

parser.add_option("-c", action="callback", callback=my_callback)

callback は関数 (または呼び出し可能オブジェクト)なので、callback オプションを定義する時にはあらかじめ my_callback() を定義しておかなければなりません。この単純なケースでは、 optparse-c が何らかの引数をとるかどうか判別できず、通常は -c が引数を伴わないことを意味します — 知りたいことはただ単に -c がコマンドライン上に現れたどうかだけです。とはいえ、場合によっては、自分のコールバック関数に任意の個数のコマンドライン引数を消費させたいこともあるでしょう。これがコールバック関数をトリッキーなものにしています; これについてはこの節の後の方で説明します。

optparse は常に四つの引数をコールバックに渡し、その他には callback_args および callback_kwargs で指定した追加引数しか渡しません。従って、最小のコールバック関数シグネチャは:

def my_callback(option, opt, value, parser):

コールバックの四つの引数については後で説明します。

callback オプションを定義する場合には、他にもいくつかオプション属性を指定できます:

type

他で使われているのと同じ意味です: "store""append" アクションの時と同じく、この属性は optparse に引数を一つ消費して type で指定した型に変換させます。 optparse は変換後の値をどこかに保存する代わりにコールバック関数に渡します。

nargs

これも他で使われているのと同じ意味です: このオプションが指定されていて、かつ nargs > 1 である場合、 optparsenargs 個の引数を消費します。このとき各引数は type 型に変換できなければなりません。変換後の値はタプルとしてコールバックに渡されます。

callback_args

その他の固定引数からなるタプルで、コールバックに渡されます

callback_kwargs

その他のキーワード引数からなる辞書で、コールバックに渡されます

36.1.4.2. コールバック関数はどのように呼び出されるか

コールバックは全て以下の形式で呼び出されます:

func(option, opt_str, value, parser, *args, **kwargs)

where

option

コールバックを呼び出している Option のインスタンスです

opt_str

は、コールバック呼び出しのきっかけとなったコマンドライン上のオプション文字列です。(長い形式のオプションに対する省略形が使われている場合、opt_str は完全な、正式な形のオプション文字列となります — 例えば、ユーザが --foobar の短縮形として --foo をコマンドラインに入力した時には、opt_str"--foobar" となります。)

value

オプションの引数で、コマンドライン上に見つかったものです。 optparse は、 type が設定されている場合、単一の引数しかとりません。 value の型はオプションの型として指定された型になります。このオプションに対する typeNone である(引数なしの) 場合、 valueNone になります。 nargs > 1 であれば、 value は適切な型をもつ値のタプルになります。

parser

現在のオプション解析の全てを駆動している OptionParser インスタンスです。この変数が有用なのは、この値を介してインスタンス属性としていくつかの興味深いデータにアクセスできるからです:

parser.largs

現在放置されている引数、すなわち、すでに消費されたものの、オプションでもオプション引数でもない引数からなるリストです。 parser.largs は自由に変更でき、たとえば引数を追加したりできます (このリストは args 、すなわち parse_args() の二つ目の戻り値になります)

parser.rargs

現在残っている引数、すなわち、opt_str および value があれば除き、それ以外の引数が残っているリストです。parser.rargs は自由に変更でき、例えばさらに引数を消費したりできます。

parser.values

オプションの値がデフォルトで保存されるオブジェクト (optparse.OptionValues のインスタンス) です。この値を使うと、コールバック関数がオプションの値を記憶するために、他の optparse と同じ機構を使えるようにするため、グローバル変数や閉包 (closure) を台無しにしないので便利です。コマンドライン上にすでに現れているオプションの値にもアクセスできます。

args

callback_args オプション属性で与えられた任意の固定引数からなるタプルです。

kwargs

callback_kwargs オプション属性で与えられた任意のキーワード引数からなるタプルです。

36.1.4.3. コールバック中で例外を送出する

オプション自体か、あるいはその引数に問題がある場合、コールバック関数は OptionValueError を送出しなければなりません。 optparse はこの例外をとらえてプログラムを終了させ、ユーザが指定しておいたエラーメッセージを標準エラー出力に出力します。エラーメッセージは明確、簡潔かつ正確で、どのオプションに誤りがあるかを示さなければなりません。さもなければ、ユーザは自分の操作のどこに問題があるかを解決するのに苦労することになります。

36.1.4.4. コールバックの例 1: ありふれたコールバック

引数をとらず、発見したオプションを単に記録するだけのコールバックオプションの例を以下に示します:

def record_foo_seen(option, opt_str, value, parser):
    parser.values.saw_foo = True

parser.add_option("--foo", action="callback", callback=record_foo_seen)

もちろん、"store_true" アクションを使っても実現できます。

36.1.4.5. コールバックの例 2: オプションの順番をチェックする

もう少し面白みのある例を示します: この例では、-b を発見して、その後で -a がコマンドライン中に現れた場合にはエラーになります。

def check_order(option, opt_str, value, parser):
    if parser.values.b:
        raise OptionValueError("can't use -a after -b")
    parser.values.a = 1
...
parser.add_option("-a", action="callback", callback=check_order)
parser.add_option("-b", action="store_true", dest="b")

36.1.4.6. コールバックの例 3: オプションの順番をチェックする (汎用的)

このコールバック (フラグを立てるが、-b が既に指定されていればエラーになる) を同様の複数のオプションに対して再利用したければ、もう少し作業する必要があります: エラーメッセージとセットされるフラグを一般化しなければなりません。

def check_order(option, opt_str, value, parser):
    if parser.values.b:
        raise OptionValueError("can't use %s after -b" % opt_str)
    setattr(parser.values, option.dest, 1)
...
parser.add_option("-a", action="callback", callback=check_order, dest='a')
parser.add_option("-b", action="store_true", dest="b")
parser.add_option("-c", action="callback", callback=check_order, dest='c')

36.1.4.7. コールバックの例 4: 任意の条件をチェックする

もちろん、単に定義済みのオプションの値を調べるだけにとどまらず、コールバックには任意の条件を入れられます。例えば、満月でなければ呼び出してはならないオプションがあるとしましょう。やらなければならないことはこれだけです:

def check_moon(option, opt_str, value, parser):
    if is_moon_full():
        raise OptionValueError("%s option invalid when moon is full"
                               % opt_str)
    setattr(parser.values, option.dest, 1)
...
parser.add_option("--foo",
                  action="callback", callback=check_moon, dest="foo")

(is_moon_full() の定義は読者への課題としましょう。)

36.1.4.8. コールバックの例5: 固定引数

決まった数の引数をとるようなコールパックオプションを定義するなら、問題はやや興味深くなってきます。引数をとるようコールバックに指定するのは、 "store""append" オプションの定義に似ています。 type を定義していれば、そのオプションは引数を受け取ったときに該当する型に変換できなければなりません。さらに nargs を指定すれば、オプションは nargs 個の引数を受け取ります。

標準の "store" アクションをエミュレートする例を以下に示します:

def store_value(option, opt_str, value, parser):
    setattr(parser.values, option.dest, value)
...
parser.add_option("--foo",
                  action="callback", callback=store_value,
                  type="int", nargs=3, dest="foo")

optparse は 3 個の引数を受け取り、それらを整数に変換するところまで面倒をみてくれます。ユーザは単にそれを保存するだけです。 (他の処理もできます; いうまでもなく、この例にはコールバックは必要ありません)

36.1.4.9. コールバックの例6: 可変個の引数

あるオプションに可変個の引数を持たせたいと考えているなら、問題はいささか手強くなってきます。この場合、 optparse では該当する組み込みのオプション解析機能を提供していないので、自分でコールバックを書かなければなりません。さらに、 optparse が普段処理している、伝統的な Unix コマンドライン解析における難題を自分で解決しなければなりません。とりわけ、コールバック関数では引数が裸の --- の場合における慣習的な処理規則:

  • either -- or - can be option arguments
  • 裸の -- (何らかのオプションの引数でない場合): コマンドライン処理を停止し、-- を無視します

  • 裸の - (何らかのオプションの引数でない場合): コマンドライン処理を停止しますが、- は残します (parser.largs に追加します)

オプションが可変個の引数をとるようにさせたいなら、いくつかの巧妙で厄介な問題に配慮しなければなりません。どういう実装をとるかは、アプリケーションでどのようなトレードオフを考慮するかによります (このため、 optparse では可変個の引数に関する問題を直接的に取り扱わないのです)。

とはいえ、可変個の引数をもつオプションに対するスタブ (stub、仲介インタフェース) を以下に示しておきます:

def vararg_callback(option, opt_str, value, parser):
    assert value is None
    value = []

    def floatable(str):
        try:
            float(str)
            return True
        except ValueError:
            return False

    for arg in parser.rargs:
        # stop on --foo like options
        if arg[:2] == "--" and len(arg) > 2:
            break
        # stop on -a, but not on -3 or -3.0
        if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):
            break
        value.append(arg)

    del parser.rargs[:len(value)]
    setattr(parser.values, option.dest, value)

...
parser.add_option("-c", "--callback", dest="vararg_attr",
                  action="callback", callback=vararg_callback)

36.1.5. optparse の拡張

optparse がコマンドラインオプションをどのように解釈するかを決める二つの重要な要素はそれぞれのオプションのアクションと型なので、拡張の方向は新しいアクションと型を追加することになると思います。

36.1.5.1. 新しい型の追加

新しい型を追加するためには、 optparseOption クラスのサブクラスを自身で定義する必要があります。このクラスには optparse における型を定義する一対の属性があります。それは TYPESTYPE_CHECKER です。

Option.TYPES

TYPES は型名のタプルです。新しく作るサブクラスでは、タプル TYPES を単純に標準のものを利用して新しく定義すると良いでしょう。

Option.TYPE_CHECKER

TYPE_CHECKER は辞書で型名を型チェック関数に対応付けるものです。型チェック関数は以下のようなシグネチャを持ちます:

def check_mytype(option, opt, value)

ここで optionOption のインスタンスであり、 opt はオプション文字列(たとえば -f)で、 value は望みの型としてチェックされ変換されるべくコマンドラインで与えられる文字列です。 check_mytype() は想定されている型 mytype のオブジェクトを返さなければなりません。型チェック関数から返される値は OptionParser.parse_args() で返されるOptionValues インスタンスに収められるか、またはコールバックに value パラメータとして渡されます。

型チェック関数は何か問題に遭遇したら OptionValueError を送出しなければなりません。 OptionValueError は文字列一つを引数に取り、それはそのまま OptionParsererror() メソッドに渡され、そこでプログラム名と文字列 "error:" が前置されてプロセスが終了する前に stderr に出力されます。

馬鹿馬鹿しい例ですが、Python スタイルの複素数を解析する "complex" オプション型を作ってみせることにします。(optparse 1.3 が複素数のサポートを組み込んでしまったため以前にも増して馬鹿らしくなりましたが、気にしないでください。)

最初に必要な import 文を書きます:

from copy import copy
from optparse import Option, OptionValueError

まずは型チェック関数を定義しなければなりません。これは後で(これから定義する Option のサブクラスの TYPE_CHECKER クラス属性の中で) 参照されることになります:

def check_complex(option, opt, value):
    try:
        return complex(value)
    except ValueError:
        raise OptionValueError(
            "option %s: invalid complex value: %r" % (opt, value))

最後に Option のサブクラスです:

class MyOption (Option):
    TYPES = Option.TYPES + ("complex",)
    TYPE_CHECKER = copy(Option.TYPE_CHECKER)
    TYPE_CHECKER["complex"] = check_complex

(もしここで Option.TYPE_CHECKERcopy() を適用しなければ、 optparse の Option クラスの TYPE_CHECKER 属性をいじってしまうことになります。 Python の常として、良いマナーと常識以外にそうすることを止めるものはありません。)

これだけです! もう新しいオプション型を使うスクリプトを他の optparse に基づいたスクリプトとまるで同じように書くことができます。ただし、 OptionParser に Option でなく MyOption を使うように指示しなければなければなりません:

parser = OptionParser(option_class=MyOption)
parser.add_option("-c", type="complex")

別のやり方として、オプションリストを構築して OptionParser に渡すという方法もあります。 add_option() を上でやったように使わないならば、OptionParser にどのクラスを使うのか教える必要はありません:

option_list = [MyOption("-c", action="store", type="complex", dest="c")]
parser = OptionParser(option_list=option_list)

36.1.5.2. 新しいアクションの追加

新しいアクションの追加はもう少しトリッキーです。というのも optparse が使っている二つのアクションの分類を理解する必要があるからです:

“store” アクション

optparse が値を現在の OptionValues の属性に格納することになるアクションです。この種類のオプションは Option のコンストラクタに dest 属性を与えることが要求されます。

“typed” アクション

コマンドラインから引数を受け取り、それがある型であることが期待されているアクションです。もう少しはっきり言えば、その型に変換される文字列を受け取るものです。この種類のオプションは Option のコンストラクタに type 属性を与えることが要求されます。

この分類には重複する部分があります。デフォルトの “store” アクションには "store", "store_const", "append", "count" などがありますが、デフォルトの “typed” オプションは "store", "append", "callback" の三つです。

アクションを追加する際に、以下の Option のクラス属性(全て文字列のリストです) の中の少なくとも一つに付け加えることでそのアクションを分類する必要があります:

Option.ACTIONS

全てのアクションは ACTIONS にリストされていなければなりません。

Option.STORE_ACTIONS

“store” アクションはここにもリストされます。

Option.TYPED_ACTIONS

“typed” アクションはここにもリストされます。

Option.ALWAYS_TYPED_ACTIONS

型を取るアクション (つまりそのオプションが値を取る) はここにもリストされます。このことの唯一の効果は optparse が、型の指定が無くアクションが ALWAYS_TYPED_ACTIONS のリストにあるオプションに、デフォルト型 "string" を割り当てるということだけです。

実際に新しいアクションを実装するには、Option の take_action() メソッドをオーバライドしてそのアクションを認識する場合分けを追加しなければなりません。

例えば、"extend" アクションというのを追加してみましょう。このアクションは標準的な "append" アクションと似ていますが、コマンドラインから一つだけ値を読み取って既存のリストに追加するのではなく、複数の値をコンマ区切りの文字列として読み取ってそれらで既存のリストを拡張します。すなわち、もし --names"string" 型の "extend" オプションだとすると、次のコマンドライン

--names=foo,bar --names blah --names ding,dong

の結果は次のリストになります

["foo", "bar", "blah", "ding", "dong"]

再び Option のサブクラスを定義します:

class MyOption(Option):

    ACTIONS = Option.ACTIONS + ("extend",)
    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
    ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)

    def take_action(self, action, dest, opt, value, values, parser):
        if action == "extend":
            lvalue = value.split(",")
            values.ensure_value(dest, []).extend(lvalue)
        else:
            Option.take_action(
                self, action, dest, opt, value, values, parser)

注意すべきは次のようなところです:

  • "extend" はコマンドラインの値を予期していると同時にその値をどこかに格納しますので、 STORE_ACTIONSTYPED_ACTIONS の両方に入ります。

  • optparse"extend" アクションに "string" 型を割り当てるように "extend" アクションは ALWAYS_TYPED_ACTIONS にも入れてあります。

  • MyOption.take_action() にはこの新しいアクション一つの扱いだけを実装してあり、他の標準的な optparse のアクションについては Option.take_action() に制御を戻すようにしてあります。

  • values は optparse_parser.Values クラスのインスタンスであり、非常に有用な ensure_value() メソッドを提供しています。 ensure_value() は本質的に安全弁付きの getattr() です。次のように呼び出します

    values.ensure_value(attr, value)
    

    valuesattr 属性が無いか None だった場合に、 ensure_value() は最初に value をセットし、それから value を返します。この振る舞いは "extend", "append", "count" のように、データを変数に集積し、またその変数がある型 (最初の二つはリスト、最後のは整数) であると期待されるアクションを作るのにとても使い易いものです。 ensure_value() を使えば、作ったアクションを使うスクリプトはオプションに保存先にデフォルト値をセットすることに煩わされずに済みます。デフォルトを None にしておけば ensure_value() がそれが必要になったときに適当な値を返してくれます。