14.3.5.1 新しい型の追加

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

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

TYPE_CHECKER は辞書で型名を型チェック関数に対応付けるものです。 型チェック関数は以下のような引数をとります。

def check_mytype(option, opt, value)

ここで optionOption のインスタンスであ り、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_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)

ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。