###
6.20.5.1 新たな型を追加する

新たな型を追加するには、`optparse` の `Option` クラス から自前のサブクラスを定義する必要があります。 このクラスは `optparse` の型を定義する二つの属性: `TYPES` と `TYPE_CHECKER` を持っています。

`TYPES` は型の名前からなるタプルです; サブクラスでは、 標準のタプルに基づいて新たなタプル `TYPES` を定義するだけです。

`TYPE_CHECKER` は型の名前を型チェック関数に対応付ける辞書 です。型チェック関数は以下の形式をとります:

    def check_foo (option : Option, opt : string, value : string)
                   -> foo

この関数はどんな名前にしてもよく、どんな型を返すようにもできます。 型チェック関数が返す値は `OptionParser.parse_args()` が返す `OptionValues` インスタンスになるか、value パラメタと してコールバック関数に渡されます。

自前の型チェック関数が問題に遭遇した場合、`OptionValueError` を送出しなければなりません。`OptionValueError` は単一の 文字列引数をとり、この引数はそのまま `OptionParser` の `error()` メソッドに渡されます。 `error()` メソッドは プログラム名と文字列 ``error:'' を渡された文字列の前に付け、 プロセスを終了する前に全てを標準エラー出力に出力します。

以下のつまらない例では、コマンドライン上の 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", action="store", type="complex", dest="c")

別の方法として、自前のオプションリストを構築して、 `OptionParser` に渡すこともできます; 上の方法で `add_option()` を使わなければ、`OptionParser` に どのオプションクラスを使うかを教える必要はありません:

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