optparse --- コマンドラインオプションのパーサー¶
ソースコード: Lib/optparse.py
引数解析ライブラリの選択¶
標準ライブラリには、引数を解析するライブラリが三つあります。
getopt: C の手続き型のgetoptAPI に忠実に対応するモジュールです。optparse:getoptを宣言的に置き換えるライブラリです。 同等の機能を提供し、アプリケーションごとにオプション解析の手続き的なロジックを実装する必要がありません。argparse:optparseの代替となるライブラリで、設計上の方針がより強く定められています。 デフォルトで多くの機能を提供する一方、引数の処理方法をアプリケーションが細かく制御する際の柔軟性は低くなります。
引数解析の設計に特別な制約がなければ、コマンドラインアプリケーションの実装には argparse を推奨します。
アプリケーション側のコードが最も少なく済み、標準で最も多くの機能を提供します。
getopt が残されている理由は、ほぼ後方互換性の維持に限られます。
ただし、getopt を使う C アプリケーションのコマンドライン引数処理を試作・テストするという限られた用途にも役立ちます。
次の場合は、argparse の代わりに optparse を使うことを検討してください。
すでに
optparseを使っており、argparseへの移行に伴う微妙な動作の変化を避けたい場合コマンドラインでオプションと位置引数を混在させる方法をさらに細かく制御する必要がある場合 (混在を完全に無効にする場合も含みます)
コマンドラインの要素を段階的に解析する処理をさらに細かく制御する必要がある場合 (
argparseも対応していますが、実際の動作が用途によっては望ましくないことがあります)-で始まる可能性のある値を受け取るオプションの扱いをさらに細かく制御する必要がある場合 (例えば、起動するサブプロセスに渡すオプション)argparseが対応していないものの、optparseの低水準のインターフェースで実装できる、その他のコマンドライン引数処理が必要な場合
こうした理由から、サードパーティのコマンドライン引数処理ライブラリを開発する場合も、optparse の方が適した基盤となる可能性があります。
具体例として、次の二つのコマンドライン引数解析の設定を見てみましょう。
一つ目は optparse、二つ目は argparse を使っています。
import optparse
if __name__ == '__main__':
parser = optparse.OptionParser()
parser.add_option('-o', '--output')
parser.add_option('-v', dest='verbose', action='store_true')
opts, args = parser.parse_args()
process(args, output=opts.output, verbose=opts.verbose)
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-o', '--output')
parser.add_argument('-v', dest='verbose', action='store_true')
parser.add_argument('rest', nargs='*')
args = parser.parse_args()
process(args.rest, output=args.output, verbose=args.verbose)
最も明らかな違いは、optparse の例ではオプションの処理を終えてから、オプション以外の引数をアプリケーション側で別途処理することです。
argparse の例では、位置引数も名前付きのオプションと同じように宣言し、処理します。
ただし、引数の組み合わせによっては、argparse の例と optparse の例で処理が異なります。
例えば、次のような違いがあります。
supplying
-o -vgivesoutput="-v"andverbose=Falsewhen usingoptparse, but a usage error withargparse(complaining that no value has been supplied for-o/--output, since-vis interpreted as meaning the verbosity flag)similarly, supplying
-o --givesoutput="--"andargs=()when usingoptparse, but a usage error withargparse(also complaining that no value has been supplied for-o/--output, since--is interpreted as terminating the option processing and treating all remaining values as positional arguments)-o=fooを指定すると、optparseではoutput="=foo"になりますが、argparseではoutput="foo"になります (オプションの値を区切る別の方法として=を特別扱いするためです)
argparse のこうした動作の違いが望ましいか、問題になるかは、コマンドラインアプリケーションの具体的な用途によって異なります。
参考
click は、もともと optparse を基に作られたサードパーティの引数処理ライブラリです。
コマンドを実装する関数にデコレーターを付け、それらを組み合わせてコマンドラインアプリケーションを開発できます。
typer や msgspec-click など、ほかのサードパーティライブラリでは、Python の型アノテーションの静的チェックとより効果的に組み合わせられる形でコマンドラインインターフェースを定義できます。
はじめに¶
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.verbose は False になります。
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] になります)。
背景¶
optparse は、C の開発者が使う getopt() 系の関数の慣習に従った、分かりやすいコマンドラインインターフェースを持つプログラムの作成を促すために設計されました。
この目的に沿って、Unix で慣習的に使われる最も一般的なコマンドラインの構文と意味だけに対応しています。
この慣習になじみがない場合は、この節を読んで確認してください。
用語集¶
- 引数 (argument)
コマンドラインでユーザが入力するテキストの塊で、シェルが
execlやexecvに引き渡すものです。Python では、引数はsys.argv[1:]の要素となります。(sys.argv[0]は実行しようとしているプログラムの名前です。引数解析に関しては、この要素はあまり重要ではありません。) Unix シェルでは、「語 (word)」という用語も使います。場合によっては
sys.argv[1:]以外の引数リストを代入する方が望ましいことがあるので、「引数」は「sys.argv[1:]またはsys.argv[1:]の代替として提供される別のリストの要素」と読むべきでしょう。- オプション (option)
プログラムの実行を指示したり、カスタマイズしたりするための追加情報を指定する引数です。 オプションにはさまざまな構文があります。 従来の Unix の構文では、
-xや-Fのようにハイフン ("-") の後に一文字を続けます。 また、複数のオプションを一つの引数にまとめることもでき、例えば-x -Fと-xFは同じ意味です。 GNU プロジェクトは、--fileや--dry-runのように、--の後にハイフンで区切った語を続ける構文を導入しました。optparseが提供するオプション構文はこの二つだけです。他に見られる他のオプション書法には以下のようなものがあります:
ハイフンの後ろに数個の文字が続くもので、例えば
-pf(このオプションは複数のオプションを一つにまとめたものとは 違います)ハイフンの後ろに語が続くもので、例えば
-file(これは技術的には上の書式と同じですが、通常同じプログラム上で一緒に使うことはありません)プラス記号の後ろに一文字、数個の文字、または語を続けたもので、例えば
+f,+rgbスラッシュ記号の後ろに一文字、数個の文字、または語を続けたもので、例えば
/f,/file
optparseはこれらのオプション構文に対応しておらず、今後も対応する予定はありません。 これは意図的なものです。 最初の三つはどの環境でも標準的ではなく、最後の構文は Windows や一部の古いプラットフォーム (VMS、MS-DOS など) だけを対象とする場合にしか意味がないためです。- オプション引数 (option argument)
オプションの後に続いてそのオプションと密接に結び付き、オプションとともに引数リストから取り出される引数です。
optparseでは、オプション引数をオプションとは別の引数として指定できます。-f foo --file foo
また、一つの引数中にも入れられます:
-ffoo --file=foo
通常、各オプションが引数を取るかどうかは決まっています。 多くの人が「省略可能なオプション引数」、つまり引数があれば受け取り、なければ受け取らないオプションを求めています。 しかし、この機能は解析を曖昧にするため、議論の余地があります。
-aが省略可能な引数を取り、-bが別のオプションである場合、-abをどう解釈すればよいでしょうか。 この曖昧さから、optparseはこの機能に対応していません。- 位置引数 (positional argument)
他のオプションが解析される、すなわち他のオプションとその引数が解析されて引数リストから除去された後に引数リストに置かれているものです。
- 必須のオプション (required option)
コマンドラインで必ず指定しなければならないオプションです。 英語で "required option" (必須のオプション) という表現は自己矛盾であることに注意してください。
optparseで必須のオプションを実装することは妨げられませんが、そのための支援機能もほとんどありません。
例えば、下記のような架空のコマンドラインを考えてみましょう:
prog -v --report report.txt foo bar
-v と --report はどちらもオプションです。--report オプションが引数をとるとすれば、report.txt はオプションの引数です。foo と bar は位置引数になります。
オプションとは何か¶
オプションはプログラムの実行を調整したり、カスタマイズしたりするための補助的な情報を与えるために使います。もっとはっきりいうと、オプションはあくまでもオプション (省略可能)であるということです。本来、プログラムはともかくもオプションなしでうまく実行できてしかるべきです。(Unix やGNU ツールセットのプログラムをランダムにピックアップしてみてください。オプションを全く指定しなくてもちゃんと動くでしょう?例外は find, tar, dd くらいです---これらの例外は、オプション文法が標準的でなく、インターフェースが混乱を招くと酷評されてきた変種のはみ出しものなのです)
多くの人が自分のプログラムに「必須のオプション」を持たせたいと考えます。しかしよく考えてください。必須なら、それは オプション(省略可能) ではないのです! プログラムを正しく動作させるのに絶対的に必要な情報があるとすれば、そこには位置引数を割り当てるべきなのです。
良くできたコマンドライン インターフェース設計として、ファイルのコピーに使われる cp ユーティリティのことを考えてみましょう。ファイルのコピーでは、コピー先を指定せずにファイルをコピーするのは無意味な操作ですし、少なくとも一つのコピー元が必要です。従って、cp は引数無しで実行すると失敗します。とはいえ、cp はオプションを全く必要としない柔軟で便利なコマンドライン文法を備えています:
cp SOURCE DEST
cp SOURCE ... DEST-DIR
これだけでも、多くの用途に対応できます。
ほとんどの cp の実装は、ファイルのコピー方法を細かく調整するオプションを備えています。
ファイルのモードや変更時刻を保持したり、シンボリックリンクをたどらないようにしたり、既存のファイルを上書きする前に確認したりできます。
それでも、一つのファイルを別のファイルにコピーする、または複数のファイルを別のディレクトリにコピーするという、cp の中心的な役割は変わりません。
位置引数とは何か¶
位置引数とは、プログラムを動作させる上で絶対的に必要な情報となる引数です。
よいユーザインターフェースとは、絶対に必要だとされるものが可能な限り少ないものです。プログラムを正しく動作させるために 17 個もの別個の情報が必要だとしたら、その 方法 はさして問題にはなりません ---ユーザはプログラムを正しく動作させられないうちに諦め、立ち去ってしまうからです。ユーザインターフェースがコマンドラインでも、設定ファイルでも、GUI やその他の何であっても同じです: 多くの要求をユーザに押し付ければ、ほとんどのユーザはただ音をあげてしまうだけなのです。
要するに、ユーザが絶対に提供しなければならない情報だけに制限する --- そして可能な限りよく練られたデフォルト設定を使うよう試みてください。もちろん、プログラムには適度な柔軟性を持たせたいとも望むはずですが、それこそがオプションの果たす役割です。繰り返しますが、設定ファイルのエントリであろうが、GUI でできた「環境設定」ダイアログ上のウィジェットであろうが、コマンドラインオプションであろうが関係ありません --- より多くのオプションを実装すればプログラムはより柔軟性を持ちますが、実装はより難解になるのです。高すぎる柔軟性はユーザを閉口させ、コードの維持をより難しくするのです。
チュートリアル¶
optparse は柔軟で強力ですが、多くの場合は簡単に使えます。
この節では、optparse を使うプログラムに共通するコードのパターンを説明します。
まず、 OptionParser クラスを import しておかなければなりません。次に、プログラムの冒頭で OptionParser インスタンスを生成しておきます:
from optparse import OptionParser
...
parser = OptionParser()
これでオプションを定義できるようになりました。基本的な構文は以下の通りです:
parser.add_option(opt_str, ...,
attr=value, ...)
各オプションには、-f や --file のようなオプション文字列が一つ以上と、いくつかのオプション属性があります。
属性は、コマンドラインでそのオプションが見つかったときに、何を受け取り、どう処理するかを optparse に指示します。
通常、各オプションには短いオプション文字列と長いオプション文字列があります。例えば:
parser.add_option("-f", "--file", ...)
短いオプション文字列と長いオプション文字列は、それぞれ好きな数だけ定義できます (どちらか一方はゼロ個でも構いません)。 ただし、全体で少なくとも一つのオプション文字列が必要です。
OptionParser.add_option() に渡すオプション文字列は、その呼び出しで定義するオプションのラベルとして機能します。
説明を簡潔にするため、以降ではコマンドラインで オプションが見つかる と表現することがあります。
実際には、optparse は オプション文字列 を見つけ、その文字列からオプションを調べます。
すべてのオプションを定義したら、optparse にプログラムのコマンドラインを解析させます。
(options, args) = parser.parse_args()
(お望みなら、 parse_args() に自作の引数リストを渡してもかまいません。とはいえ、実際にはそうした必要はほとんどないでしょう: このメソッドはデフォルトで sys.argv[1:] を使うからです。)
parse_args() は二つの値を返します:
全てのオプションに対する値の入ったオブジェクト
options--- 例えば、--fileが単一の文字列引数をとる場合、options.fileはユーザが指定したファイル名になります。オプションを指定しなかった場合にはNoneになりますオプションの解析後に残った位置引数からなるリスト
args
このチュートリアルの節では、最も重要な四つのオプション属性: action, type, dest (destination), help についてしか触れません。このうち最も重要なのは action です。
オプション・アクションを理解する¶
アクションは、コマンドラインでオプションが見つかったときの処理を optparse に指示します。
optparse には一定のアクションが組み込まれています。
新しいアクションの追加は高度な話題で、optparse の拡張 の節で扱います。
ほとんどのアクションは、何らかの変数に値を保存するよう optparse に指示します。
例えば、コマンドラインから文字列を取り出して options の属性に保存します。
オプションのアクションを指定しない場合、optparse はデフォルトで store を使います。
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)
optparse はオプション文字列 -f を見つけると、次の引数 foo.txt を取り出して options.filename に保存します。
そのため、この parse_args() の呼び出し後には、options.filename は "foo.txt" になります。
optparse は、ほかにも int や float などのオプションの型に対応しています。
整数の引数を受け取るオプションの例を示します。
parser.add_option("-n", type="int", dest="num")
このオプションには長いオプション文字列がありませんが、それでも問題ありません。
また、デフォルトのアクションは store なので、アクションを明示していません。
架空のコマンドラインをもう一つ解析してみましょう。今度は、オプション引数をオプションの右側にぴったりくっつけて一緒くたにします: -n42 (一つの引数のみ) は -n 42 (二つの引数からなる) と等価になるので
(options, args) = parser.parse_args(["-n42"])
print(options.num)
は 42 を出力します。
型を指定しない場合、optparse は string とみなします。
また、デフォルトのアクションは store なので、最初の例はもっと短く書けます。
parser.add_option("-f", "--file", dest="filename")
保存先を指定しない場合、optparse はオプション文字列から適切なデフォルト値を決めます。
最初の長いオプション文字列が --foo-bar なら、デフォルトの保存先は foo_bar です。
長いオプション文字列がなければ、optparse は最初の短いオプション文字列を使います。
-f のデフォルトの保存先は f です。
optparse には組み込みの型として complex もあります。
型の追加については optparse の拡張 の節で説明します。
ブール値 (フラグ) オプションの処理¶
特定のオプションが見つかったときに変数を真または偽にするフラグオプションは、よく使われます。
optparse は、store_true と store_false という二つのアクションでこれに対応しています。
例えば、-v で有効にし、-q で無効にする verbose フラグは次のように定義できます。
parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose")
ここでは二つのオプションに同じ保存先を指定していますが、全く問題ありません。(下記のように、デフォルト値の設定を少し注意深く行わなければならないだけです。)
optparse はコマンドラインで -v を見つけると options.verbose を True に設定し、-q を見つけると options.verbose を False に設定します。
その他のアクション¶
optparse が対応するその他のアクションには、次のものがあります。
"store_const"Option.constであらかじめ指定した定数を保存します"append"オプションの引数を指定のリストに追加します
"count"指定のカウンタを 1 増やします
"callback"指定の関数を呼び出します
これらのアクションについては、 リファレンスガイド 節および オプション処理コールバック 節で触れます。
デフォルト値¶
ここまでの例はどれも、特定のコマンドラインオプションが見つかったときに変数 (「保存先」) を設定するものでした。
そのオプションが一度も見つからなければ、どうなるでしょうか。
デフォルト値を指定していないため、すべて None に設定されます。
通常はこれで問題ありませんが、もっと細かく制御したい場合もあります。
optparse では、保存先ごとにデフォルト値を指定できます。
この値はコマンドラインの解析前に代入されます。
まず、verbose/quiet の例を考えてみましょう。
-q が見つからない限り optparse が verbose を True に設定するようにするには、次のように書きます。
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 になります; 特定の目的変数に対するデフォルト値として有効なのは、最後に指定した値だからです。
デフォルト値をすっきりと指定するには、 OptionParser の set_defaults() メソッドを使います。このメソッドは parse_args() を呼び出す前ならいつでも使えます:
parser.set_defaults(verbose=True)
parser.add_option(...)
(options, args) = parser.parse_args()
前の例と同様、あるオプションの値の保存先に対するデフォルトの値は最後に指定した値になります。コードを読みやすくするため、デフォルト値を設定するときには両方のやり方を混ぜるのではなく、片方だけを使うようにしましょう。
ヘルプの生成¶
optparse のヘルプや使い方の説明を自動生成する機能は、ユーザが使いやすいコマンドラインインターフェースを作るのに役立ちます。
必要なのは、各オプションに 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() を呼び出した場合、次の内容を標準出力に表示します。
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]
(ヘルプオプションによってヘルプが表示された場合、optparse は表示後に終了します。)
この例では、optparse ができるだけ適切なヘルプメッセージを生成できるよう、いくつもの工夫をしています。
スクリプト自体の利用法を表すメッセージを定義します:
usage = "usage: %prog [options] arg1 arg2"
optparseは使い方の説明に含まれる%progを、現在のプログラム名、つまりos.path.basename(sys.argv[0])に展開します。 展開した文字列は、オプションの詳しいヘルプの前に表示されます。使い方の説明を指定しない場合、
optparseは簡素ながら妥当なデフォルト値"Usage: %prog [options]"を使います。 スクリプトが位置引数を取らなければ、これで十分です。どのオプションにもヘルプ文字列を定義していますが、行の折り返しは気にしていません。
optparseが行を折り返し、ヘルプの表示を整えます。オプションが値をとるということは自動的に生成されるヘルプメッセージの中で分かります。例えば、"mode" option の場合にはこのようになります:
-m MODE, --mode=MODE
ここで "MODE" はメタ変数と呼ばれ、ユーザが
-m/--modeに指定する引数を表します。 デフォルトでは、optparseは保存先の変数名を大文字に変換してメタ変数として使います。 ただし、これでは望ましくない場合もあります。 例えば、--filenameオプションではmetavar="FILE"を明示的に設定しているため、次のオプションの説明が自動生成されます。-f FILE, --filename=FILE
この機能の重要さは、単に表示スペースを節約するといった理由にとどまりません: 上の例では、手作業で書いたヘルプテキストの中でメタ変数として
FILEを使っています。その結果、ユーザに対してやや堅苦しい表現の書法-f FILEと、より平易に意味付けを説明した "write output to FILE" との間に対応があるというヒントを与えています。これは、エンドユーザにとってより明解で便利なヘルプテキストを作成する単純でありながら効果的な手法なのです。デフォルト値を持つオプションでは、ヘルプ文字列に
%defaultを含めることができます。optparseはこれを、オプションのデフォルト値にstr()を適用した結果に置き換えます。 デフォルト値がない場合 (またはデフォルト値がNoneの場合)、%defaultはnoneに展開されます。
オプションをグループ化する¶
たくさんのオプションを扱う場合、オプションをグループ分けするとヘルプ出力が見やすくなります。 OptionParser は、複数のオプションをまとめたオプショングループを複数持つことができます。
オプションのグループは、 OptionGroup を使って作成します:
- class optparse.OptionGroup(parser, title, description=None)¶
ここでは:
parser は、このグループが属する
OptionParserのインスタンスですtitle はグループのタイトルです
description はオプションで、グループの長い説明です
OptionGroup は (OptionParser のように) OptionContainer を継承していて、オプションをグループに追加するために add_option() メソッドを利用できます。
全てのオプションを定義したら、 OptionParser の add_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を返します。
バージョン番号の出力¶
短い使い方の説明と同じように、optparse はプログラムのバージョン文字列も表示できます。
この文字列は OptionParser の version 引数として指定します。
parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")
%prog は usage の場合と同じように展開されます。
それ以外の部分では、version に好きな内容を含められます。
version を指定すると、optparse はパーサーに --version オプションを自動で追加します。
コマンドラインでこのオプションを見つけると、version 文字列の %prog を置き換えて展開し、標準出力に表示して終了します。
例えば、/usr/bin/foo という名前のスクリプトなら:
$ /usr/bin/foo --version
foo 1.0
以下の二つのメソッドを使って、version 文字列を表示・取得できます。
- OptionParser.print_version(file=None)¶
現在のプログラムのバージョン (
self.version) を file (デフォルト: stdout) へ表示します。print_usage()と同じく、self.versionの中の全ての%progが現在のプログラム名に置き換えられます。self.versionが空文字列だだったり未定義だったときは何もしません。
- OptionParser.get_version()¶
print_version()と同じですが、バージョン文字列を表示する代わりに返します。
optparse のエラー処理¶
optparse が対処するエラーは、大きく分けてプログラマーの誤りとユーザの誤りの二種類あります。
プログラマーの誤りは通常、OptionParser.add_option() の呼び出しの誤りです。
例えば、無効なオプション文字列、不明なオプション属性、必須のオプション属性の指定漏れなどです。
これらには通常の方法で対処します。
例外 (optparse.OptionError または TypeError) を送出し、プログラムを異常終了させます。
ユーザの誤りは、コードがどれだけ安定していても必ず起こるため、その対処はずっと重要です。
optparse は、不正なオプション引数 (整数の引数を取る -n に -n 4x を指定する場合) や引数の指定漏れ (引数を取る -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() メソッドをオーバーライドする必要があります。
全てをつなぎ合わせる¶
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()
リファレンスガイド¶
parserを作る¶
optparse を使うには、まず OptionParser のインスタンスを作成します。
- class optparse.OptionParser(...)¶
OptionParser のコンストラクタの引数はどれも必須ではありませんが、いくつものキーワード引数がオプションとして使えます。これらはキーワード引数として渡さなければなりません。すなわち、引数が宣言されている順番に頼ってはいけません。
usage(デフォルト:"%prog [options]")プログラムの使い方を誤った場合やヘルプオプションを指定した場合に表示する、使い方の概要です。
optparseはこの文字列を表示するとき、%progをos.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だけのバージョンオプションを自動で追加します。 部分文字列%progはusageと同じように展開されます。conflict_handler(デフォルト:"error")オプション文字列が衝突するようなオプションがパーザに追加されたときにどうするかを指定します。 オプション間の衝突 節を参照して下さい。
description(デフォルト:None)プログラムの概要を簡潔に説明する一段落のテキストです。
optparseは、この段落を現在の端末の幅に合わせて整形し、ユーザがヘルプを要求したときに表示します (usageの後、オプションの一覧の前に表示します)。formatter(デフォルト: 新しいIndentedHelpFormatter)ヘルプテキストの表示に使う optparse.HelpFormatter のインスタンスです。
optparseは、このための具象クラスとして IndentedHelpFormatter と TitledHelpFormatter を提供しています。add_help_option(デフォルト:True)真の場合、
optparseはオプション文字列が-hと--helpのヘルプオプションをパーサーに追加します。progusageやversionの中の%progを展開するときにos.path.basename(sys.argv[0])の代わりに使われる文字列です。epilog(デフォルト:None)オプションのヘルプの後に表示されるヘルプテキスト.
パーザへのオプション追加¶
パーザにオプションを加えていくにはいくつか方法があります。推奨するのは チュートリアル 節で示したような 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 を直接インスタンス化しないでください。)
オプションの定義¶
各々の Option インスタンス、は -f や --file といった同義のコマンドラインオプションからなる集合を表現しています。一つの Option には任意の数のオプションを短い形式でも長い形式でも指定できます。ただし、少なくとも一つは指定しなければなりません。
正しい方法で Option インスタンスを生成するには、 OptionParser の add_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の処理を決めます。optparseに組み込まれている標準のオプションアクションは次のとおりです。"store"オプションの引数を保存します (デフォルトの動作です)
"store_const"Option.constであらかじめ指定した定数を保存します"store_true"Trueを保存します"store_false"Falseを保存します"append"オプションの引数を指定のリストに追加します
"append_const"Option.constであらかじめ指定した定数をリストに追加します"count"指定のカウンタを 1 増やします
"callback"指定の関数を呼び出します
"help"全てのオプションとそのドキュメントの入った使用法メッセージを出力します
(アクションを指定しない場合、デフォルトは
"store"になります。このアクションでは、typeおよびdestオプション属性を指定できます。 標準的なオプション・アクション を参照してください。)
このように、ほとんどのアクションは、どこかに値を保存したり更新したりします。
optparse は、そのための特別なオブジェクトを常に作成します。
このオブジェクトは通常 options と呼ばれる、optparse.Values のインスタンスです。
- class optparse.Values¶
An object holding parsed argument names and values as attributes. Normally created by calling when calling
OptionParser.parse_args(), and can be overridden by a custom subclass passed to the values argument ofOptionParser.parse_args()(as described in 引数を解析する).
オプション引数 (およびその他のさまざまな値) は、オプション属性 dest (保存先) に従って、このオブジェクトの属性に保存されます。
例えばこれを呼び出した場合
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 だけなのです。
オプション属性¶
- class optparse.Option¶
コマンドライン引数を一つ表すオブジェクトです。 コンストラクターにキーワード引数としてさまざまな属性を渡します。 通常は直接作成せず、
OptionParser.add_option()で作成します。OptionParserの option_class 引数で、独自のクラスに置き換えることができます。
次のオプション属性を、OptionParser.add_option() のキーワード引数として指定できます。
そのオプションに関係しない属性を指定した場合や、必須の属性を指定しなかった場合、optparse は OptionError を送出します。
- 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 より大きい場合、optparseは値のタプルをdestに保存します。
- Option.const¶
定数を格納する動作のための、その定数です。
- Option.choices¶
"choice"型オプションに対してユーザが選べる選択肢となる文字列のリストです。
- Option.callback¶
アクションが
"callback"であるオプションに対し、このオプションがあったときに呼ばれる呼び出し可能オブジェクトです。呼び出し時に渡される引数の詳細については、 オプション処理コールバック を参照してください。
標準的なオプション・アクション¶
各オプションアクションの要件と効果は少しずつ異なります。
多くのアクションには、optparse の動作を指定するための関連するオプション属性がいくつかあります。
一部のアクションには必須の属性があり、そのアクションを使うオプションでは必ず指定しなければなりません。
"store"[関連:type,dest,nargs,choices]オプションの後には必ず引数が続きます。引数は
typeに従って値に変換されてdestに保存されます。nargs> 1 の場合、複数の引数をコマンドラインから取り出します。引数は全てtypeに従って変換され、destにタプルとして保存されます。 標準のオプション型 節を参照してください。choicesを(文字列のリストかタプルで) 指定した場合、型のデフォルト値は"choice"になります。typeを指定しない場合、デフォルトの値は"string"です。destを指定しない場合、optparseは最初の長いオプション文字列から保存先を決めます (例えば--foo-barならfoo_barになります)。 長いオプション文字列がなければ、optparseは最初の短いオプション文字列から保存先を決めます (例えば-fならfになります)。以下はプログラム例です:
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]以下はプログラム例です:
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"の特殊な場合で、destにTrueを保存します。"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 # 通常、ヘルプオプションは自動で追加されますが、 # add_help_option 引数で追加を抑制できます。 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
ヘルプメッセージを表示した後、
optparseはsys.exit(0)でプロセスを終了します。"version"OptionParser に指定したバージョン番号を標準出力に表示して終了します。 バージョン番号の整形と表示は、実際には OptionParser の
print_version()メソッドが行います。 通常、OptionParser コンストラクターにversion引数を指定した場合にだけ関係します。helpオプションと同様に、optparseが必要に応じて自動で追加するため、versionオプションを自分で作ることはほとんどありません。
標準のオプション型¶
optparse には、"string"、"int"、"choice"、"float"、"complex" の五つのオプション型が組み込まれています。
新しいオプション型を追加する必要がある場合は、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 を送出します。
引数を解析する¶
OptionParser を作成してオプションを追加していく上で大事なポイントは、 parse_args() メソッドの呼び出しです。
- OptionParser.parse_args(args=None, values=None)¶
args に含まれるコマンドラインオプションを解析します。
入力引数は次のとおりです。
args処理する引数のリスト (デフォルト:
sys.argv[1:])valuesオプション引数を格納する
Valuesのオブジェクト (デフォルト: 新しいValuesのインスタンス) -- 既存のオブジェクトを指定した場合、オプションのデフォルトは初期化されません
戻り値は二つの要素を持つ
(options, args)で、各要素は次のとおりです。optionsvalues として渡したオブジェクトそのもの、または
optparseが作成したoptparse.Valuesのインスタンスargs全てのオプションの処理が終わった後で残った位置引数
一番普通の使い方は一切キーワード引数を使わないというものです。 values を指定した場合、それは繰り返される setattr() の呼び出し (大雑把に言うと保存される各オプション引数につき一回ずつ) で更新されていき、 parse_args() で返されます。
parse_args() が引数リストでエラーに遭遇した場合、 OptionParser の error() メソッドを適切なエンドユーザ向けのエラーメッセージとともに呼び出します。この呼び出しにより、最終的に終了ステータス 2 (伝統的な Unix におけるコマンドラインエラーの終了ステータス) でプロセスを終了させることになります。
オプション解析器への問い合わせと操作¶
オプションパーザのデフォルトの振る舞いは、ある程度カスタマイズすることができます。また、オプションパーザの中を調べることもできます。 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 がある場合、Trueを返します。
- OptionParser.remove_option(opt_str)¶
OptionParserに opt_str に対応するオプションがある場合、そのオプションを削除します。該当するオプションに他のオプション文字列が指定されていた場合、それらのオプション文字列は全て無効になります。 opt_str がこのOptionParserオブジェクトのどのオプションにも属さない場合、ValueErrorを送出します。
オプション間の衝突¶
注意が足りないと、衝突するオプションを定義してしまうことがあります:
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" なので、先に追加したオプションのオプション文字列のリストから -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
クリーンアップ¶
OptionParser インスタンスはいくつかの循環参照を抱えています。このことは Python のガーベジコレクタにとって問題になるわけではありませんが、使い終わった OptionParser に対して destroy() を呼び出すことでこの循環参照を意図的に断ち切るという方法を選ぶこともできます。この方法は特に長時間実行するアプリケーションで OptionParser から大きなオブジェクトグラフが到達可能になっているような場合に有用です。
その他のメソッド¶
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") # 下の設定で上書きされます parser.add_option("--novice", action="store_const", dest="mode", const="novice", default="advanced") # 上の設定を上書きします
こうした混乱を避けるために
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")
オプション処理コールバック¶
optparse に組み込まれたアクションや型では要件を満たせない場合、optparse を拡張するか、コールバックオプションを定義するかの二つの方法があります。
optparse の拡張はより汎用的ですが、単純な用途の多くには大がかりすぎます。
単純なコールバックだけで足りることもよくあります。
callback オプションの定義は二つのステップからなります:
"callback"アクションを使ってオプション自体を定義するコールバックを書く。コールバックは少なくとも後で説明する 4 つの引数をとる関数 (またはメソッド) でなければなりません
callbackオプションの定義¶
callback オプションを最も簡単に定義するには、 OptionParser.add_option() メソッドを使います。 action の他に指定しなければならない属性は callback すなわちコールバックする関数自体です:
parser.add_option("-c", action="callback", callback=my_callback)
callback は関数 (またはその他の呼び出し可能オブジェクト) なので、このコールバックオプションを作成する時点で my_callback() が定義されている必要があります。
この単純な例では、optparse は -c が引数を取るかどうかさえ知りません。
通常、このようなオプションは引数を取らず、コマンドラインに -c があるかどうかだけが重要です。
ただし、コールバックで任意の個数のコマンドライン引数を取り出したい場合もあります。
そうなるとコールバックの実装は難しくなります。
これについては、この節の後半で説明します。
optparse は常に特定の四つの引数をコールバックに渡します。
追加の引数を渡すのは、callback_args と callback_kwargs で指定した場合だけです。
したがって、コールバック関数の最小限のシグネチャは次のようになります。
def my_callback(option, opt, value, parser):
コールバックの四つの引数については後で説明します。
callback オプションを定義する場合には、他にもいくつかオプション属性を指定できます:
type通常と同じ意味です。
"store"や"append"アクションと同様に、引数を一つ取り出してtypeに変換するようoptparseに指示します。 ただし、optparseは変換した値をどこかに保存する代わりに、コールバック関数に渡します。nargsこれも通常と同じ意味です。 1 より大きな値を指定すると、
optparseはnargs個の引数を取り出します。 各引数はtypeに変換できなければなりません。 変換した値のタプルがコールバックに渡されます。callback_argsその他の位置引数からなるタプルで、コールバックに渡されます
callback_kwargsその他のキーワード引数からなる辞書で、コールバックに渡されます
コールバック関数はどのように呼び出されるか¶
コールバックは全て以下の形式で呼び出されます:
func(option, opt_str, value, parser, *args, **kwargs)
ここでは:
optionコールバックを呼び出している
Optionのインスタンスですopt_strは、コールバック呼び出しのきっかけとなったコマンドライン上のオプション文字列です。(長い形式のオプションに対する省略形が使われている場合、
opt_strは完全な、正式な形のオプション文字列となります --- 例えば、ユーザが--foobarの短縮形として--fooをコマンドラインに入力した時には、opt_strは"--foobar"となります。)valueコマンドラインでこのオプションに指定された引数です。
optparseはtypeが設定されている場合にだけ引数を受け取り、valueはオプションで指定された型になります。 このオプションのtypeがNoneの場合 (引数を取らない場合)、valueはNoneです。nargs> 1 の場合、valueは適切な型の値を格納したタプルになります。parser現在のオプション解析の全てを駆動している
OptionParserインスタンスです。この変数が有用なのは、この値を介してインスタンス属性としていくつかの興味深いデータにアクセスできるからです:parser.largs現在放置されている引数、すなわち、すでに消費されたものの、オプションでもオプション引数でもない引数からなるリストです。
parser.largsは自由に変更でき、たとえば引数を追加したりできます (このリストはargs、すなわちparse_args()の二つ目の戻り値になります)parser.rargs現在まだ処理していない引数のリストです。
opt_strと (存在する場合は)valueを取り除いた後、その後ろに続く引数だけが残っています。parser.rargsは自由に変更でき、例えば追加の引数を取り出せます。parser.valuesthe object where option values are by default stored (an instance of optparse.OptionValues). This lets callbacks use the same mechanism as the rest of
optparsefor storing option values; you don't need to mess around with globals or closures. You can also access or modify the value(s) of any options already encountered on the command-line.
argscallback_argsオプション属性で与えられた任意の位置引数からなるタプルです。kwargscallback_kwargsオプション属性で与えられた任意のキーワード引数からなる辞書です。
コールバック中で例外を送出する¶
オプションやその引数に問題がある場合、コールバック関数は OptionValueError を送出してください。
optparse はこれを捕捉し、指定されたエラーメッセージを標準エラー出力に表示してプログラムを終了します。
メッセージは明確、簡潔、正確にし、問題のあるオプションを示してください。
そうしないと、ユーザはどこを間違えたのか判断しにくくなります。
コールバックの例 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" アクションを使っても実現できます。
コールバックの例 2: オプションの順番をチェックする¶
もう少し複雑な例を示します。
-a が見つかったことを記録しますが、コマンドラインで -b の後に現れた場合はエラーにします。
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")
コールバックの例 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')
コールバックの例 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() の定義は読者への課題としましょう。)
コールバックの例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 が三つの引数を取り出して整数に変換してくれるので、コールバックは値を保存するだけで済みます。
(もちろん、保存以外の処理をしても構いません。
この例の処理だけならコールバックは不要です。)
コールバックの例6: 可変個の引数¶
オプションが可変個の引数を取るようにしたい場合、処理は複雑になります。
optparse にはそのための機能が組み込まれていないので、コールバックを書く必要があります。
また、通常は optparse が処理してくれる、従来の Unix のコマンドライン解析に特有の細かな規則にも対処しなければなりません。
特に、コールバックでは単独の -- と - に関する慣習的な規則を実装する必要があります。
--と-はどちらもオプション引数になりえます裸の
--(何らかのオプションの引数でない場合): コマンドライン処理を停止し、--を無視します裸の
-(何らかのオプションの引数でない場合): コマンドライン処理を停止しますが、-は残します (parser.largsに追加します)
可変個の引数を取るオプションには、微妙で扱いの難しい問題がいくつかあります。
具体的な実装は、アプリケーションでどのようなトレードオフを受け入れるかによって決まります (このため、optparse はこのような機能を直接は提供していません)。
それでは、可変個の引数をとるオプション用のコールバックを試しに実装してみます。
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:
# --foo のようなオプションで止まります
if arg[:2] == "--" and len(arg) > 2:
break
# -a では止まりますが、-3 や -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)
optparse の拡張¶
optparse によるコマンドラインオプションの解釈を左右する主な要素は、各オプションのアクションと型です。
そのため、拡張の最も一般的な方向性は、新しいアクションや型を追加することです。
新しい型の追加¶
新しい型を追加するには、optparse の Option クラスから独自のサブクラスを定義する必要があります。
このクラスには、optparse の型を定義する TYPES と TYPE_CHECKER という二つの属性があります。
- Option.TYPE_CHECKER¶
TYPE_CHECKERは辞書で型名を型チェック関数に対応付けるものです。型チェック関数は以下のようなシグネチャを持ちます:def check_mytype(option, opt, value)
ここで
optionはOptionのインスタンスであり、optはオプション文字列(たとえば-f)で、valueは望みの型としてチェックされ変換されるべくコマンドラインで与えられる文字列です。check_mytype()は想定されている型mytypeのオブジェクトを返さなければなりません。型チェック関数から返される値はOptionParser.parse_args()で返されるOptionValues インスタンスに収められるか、またはコールバックにvalueパラメータとして渡されます。型チェック関数は何か問題に遭遇したら
OptionValueErrorを送出しなければなりません。OptionValueErrorは文字列一つを引数に取り、それはそのままOptionParserのerror()メソッドに渡され、そこでプログラム名と文字列"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_CHECKER を copy() でコピーしないと、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)
新しいアクションの追加¶
新しいアクションの追加は、少し複雑です。
optparse がアクションを次のように分類していることを理解する必要があります。
- "store" アクション
actions that result in
optparsestoring a value to an attribute of the current OptionValues instance; these options require adestattribute to be supplied to the Option constructor.- "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¶
常に型を取るアクション (そのオプションが常に値を取るアクション) は、ここにも登録します。 この指定の効果は、
ALWAYS_TYPED_ACTIONSに登録されたアクションを持ち、型を明示していないオプションに対して、optparseがデフォルトの型"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_ACTIONSとTYPED_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)
valuesにattr属性が無いかNoneだった場合に、ensure_value()は最初にvalueをセットし、それからvalueを返します。この振る舞いは"extend","append","count"のように、データを変数に集積し、またその変数がある型 (最初の二つはリスト、最後のは整数) であると期待されるアクションを作るのにとても使い易いものです。ensure_value()を使えば、作ったアクションを使うスクリプトはオプションに保存先にデフォルト値をセットすることに煩わされずに済みます。デフォルトをNoneにしておけばensure_value()がそれが必要になったときに適当な値を返してくれます。
例外¶
- exception optparse.OptionConflictError¶
OptionParserに衝突するオプションを追加した場合に送出されます。
- exception optparse.OptionValueError¶
コマンドラインで無効なオプション値が見つかった場合に送出されます。
- exception optparse.BadOptionError¶
コマンドラインで無効なオプションを指定した場合に送出されます。
- exception optparse.AmbiguousOptionError¶
コマンドラインで曖昧なオプションを指定した場合に送出されます。