3.3.1 基本的なカスタマイズ

__new__( cls[, args...])

クラス cls の新しいインスタンスを作るために呼び出されます。 __new__() は静的メソッドで (このメソッドは特別扱いされている ので、明示的に静的メソッドと宣言する必要はありません)、インスタンスを 生成するよう要求されているクラスを第一引数にとります。残りの引数はオブ ジェクトのコンストラクタの式 (クラスの呼び出し文) に渡されます。 __new__() の戻り値は新しいオブジェクトのインスタンス (通常は cls のインスタンス) でなければなりません。

典型的な実装では、クラスの新たなインスタンスを生成するときには "super(currentclass, cls).__new__(cls[, ...])"に適切な引数を指定してスーパクラスの __new__() メソッドを呼 び出し、新たに生成されたインスタンスに必要な変更を加えてから返します。

__new__()cls のインスタンスを返した場合、 "__init__(self[, ...])" のようにしてインスタンスの __init__() が呼び出されます。このとき、self は新たに生成 されたインスタンスで、残りの引数は __new__() に渡された引数と 同じになります。

__new__()cls のインスタンスを返さない場合、インスタ ンスの __init__() メソッドは呼び出されません。

__new__() の主な目的は、変更不能な型 (int, str, tuple など) のサブクラスでインスタンス生成をカスタマイズすることにあります。

__init__( self[, ...])
インスタンスが生成された際に呼び出されるコンストラクタ (constructor) です。引数はそのクラスのコンストラクタ式に渡した引数になります。 基底クラスが__init__() メソッドを持っている場合、 導出クラスの __init__() メソッドでは、 例えば "BaseClass.__init__(self, [args...])" の ように、必要ならば明示的に基底クラスの__init__() メソッドを 呼び出して、インスタンスの基底クラスに関わる部分が正しく初期化される ようにしなければなりません。コンストラクタには、値を返してはならない という特殊な制限があります; 値を返すようにすると、実行時に TypeError の送出を引き起こします。

__del__( self)
インスタンスが消滅させられる際に呼び出されます。このメソッドは デストラクタ (destructor) とも呼ばれます。 基底クラスが__del__() メソッドを持っている場合、 導出クラスの __del__() メソッドでは、必要ならば明示的に 基底クラスの__del__() メソッドを 呼び出して、インスタンスの基底クラスに関わる部分が正しく消滅処理 されるようにしなければなりません。 __del__() メソッドでインスタンスに対する新たな参照を 作ることで、インスタンスの消滅を遅らせることができます (とはいえ、推奨しません!)。このようにすると、新たに作成された 参照がその後削除された際にもう一度 __del__() メソッド が呼び出されます。 インタプリタが終了する際に残っているオブジェクトに対して、 __del__() メソッドが呼び出される保証はありません。

注意: "del x" は直接 x.__del__() を呼び出しません -- 前者は x への参照カウント (reference count) を 1 つ減らし、 後者は x への参照カウントがゼロになった際にのみ呼び出されます。 オブジェクトへの参照カウントがゼロになるのを妨げる可能性のある よくある状況には、以下のようなものがあります: 複数のオブジェクト間 における循環参照 (二重リンクリストや、親と子へのポインタを持つツリー データ構造); 例外を捕捉した関数におけるスタックフレーム上にある オブジェクトへの参照 (sys.exc_traceback に記憶されている トレースバックが、スタックフレームを生き延びさせます); または、対話モードでハンドルされなかった例外を送出した スタックフレーム上にあるオブジェクトへの参照 (sys.last_traceback に記憶されているトレースバックが、 スタックフレームを生き延びさせます); 最初の状況については、明示的に循環参照を壊すしか解決策は ありません; 後者の二つの状況は、Nonesys.exc_tracebacksys.last_traceback に 入れることで解決できます。ごみオブジェクトと化した循環参照は、 オプションの循環参照検出機構 (cycle detector) が有効にされて いる場合 (これはデフォルトの設定です) には検出されますが、 検出された循環参照を消去するのは Python レベルで __del__() メソッドが定義されていない場合だけです。 __del__() メソッドが循環参照検出機構でどのように 扱われるか、とりわけ garbage 値の記述に関しては、 gc モジュール の ドキュメントを参照してください。

警告: __del__() メソッドの呼び出しが起きるのは不安定な状況 なので、__del__() の実行中に発生した例外は無視され、 代わりに sys.stderr に警告が出力されます。また、 (例えばプログラムの実行終了による) モジュールの削除に伴って __del__() が呼び出される際には、__del__() メソッドが参照している他のグローバル変数はすでに削除されている かもしれません。この理由から、 __del__() メソッドでは 外部の不変関係を維持する上で絶対最低限必要なことだけをすべき です。バージョン 1.5 からは、単一のアンダースコアで始まるような グローバル変数は、他のグローバル変数が削除される前にモジュール から削除されるように Python 側で保証しています; これらの アンダースコア付きグローバル変数は、__del__() が呼び 出された際に、import されたモジュールがまだ残っているか確認 する上で役に立ちます。

__repr__( self)
組み込み関数repr() や、文字列への 変換 (逆クオート表記: reverse quote) の際に呼び出され、 オブジェクトを表す ``公式の (official)'' 文字列を計算します。 可能な場合には、この値は同じ値を持ったオブジェクトを (適切な環境で) 再生成するために使えるような有効な Python 式に 似せるべきです。それが不可能なら、"<...some useful description...>" 形式の文字列を返してください。 戻り値は文字列オブジェクトでなければなりません。 クラスが __repr__() を定義しているが __str__() を定義していない場合、そのクラスのインスタンスに対する ``非公式の (informal)'' 文字列表現が必要なときにも __repr__() が使われます。

この関数はデバッグの際によく用いられるので、たくさんの情報を 含み、あいまいでないような表記にすることが重要です。

__str__( self)
組み込み関数 str() および print 文によって呼び出され、 オブジェクトを表す ``非公式の'' 文字列を計算します。 このメソッドは、有効な Python 式を返さなくても良いという点で、 __repr__() と異なります: その代わり、より便利で分かりやすい 表現を返すようにしてください。戻り値は文字列オブジェクトで なければなりません。

__lt__( self, other)
__le__( self, other)
__eq__( self, other)
__ne__( self, other)
__gt__( self, other)
__ge__( self, other)
バージョン 2.1 で 新たに追加 された仕様です。 これらのメソッドは ``拡張比較 (rich comparison)'' メソッドと呼ばれ、 下記の __cmp__() に優先して呼び出されます。 演算子シンボルとメソッド名の対応は以下の通りです: x<yx.__lt__(y) を呼び出します; x<=yx.__le__(y) を呼び出します; x==yx.__eq__(y) を呼び出します; x!=y および x<>yx.__ne__(y) を呼び出します; x>yx.__gt__(y) を呼び出します; x>=yx.__ge__(y) を呼び出します。 これらのメソッドは任意の値を返すことができますが、比較演算子が ブール値のコンテキストで使われた場合、戻り値はブール値として 解釈可能でなければなりません。そうでない場合には TypeError が送出されます。 慣習的には、 False は偽値、 True は真値として用いられ ます。

比較演算子間には、暗黙的な論理関係はありません。すなわち、 x==y が真である場合、暗黙のうちに x!=y が偽になるわけではありません。 従って、__eq__ を実装する際、演算子が期待通りに 動作するようにするために __ne__ も定義する必要があります。

これらのメソッドには、(左引数が演算をサポートしないが、右引数は サポートする場合に用いられるような) 鏡像となる (引数を入れ替えた) バージョンは存在しません; むしろ、__lt__()__gt__() は互いに鏡像であり、__le__()__ge__() 、および __eq__()__ne__() はそれぞれ互いに鏡像です。

拡張比較メソッドの引数には型強制 (coerce) が起こりません。 与えられた引数ペアの間で演算が実装されていない場合、拡張比較 メソッドは NotImplemented を返します。

__cmp__( self, other)
拡張比較 (上参照) が定義されていない場合、比較演算によって 呼び出されます。self < other である場合には負の値、 self == other ならばゼロ、self > other であれば 正の値を返さなければなりません。演算 __cmp__()__eq__() および __ne__() がいずれも定義されていない場合、 クラスインスタンスはオブジェクトのアイデンティティ (``アドレス'') で比較されます。自作の比較演算をサポートするオブジェクトや、 辞書のキーとして使えるオブジェクトを生成するには、 __hash__() に関する記述を参照してください。 (注意: __cmp__() が例外を伝播しないという制限は Python 1.5 から除去されました。)

__rcmp__( self, other)
バージョン 2.1 で 変更 された仕様: もはやサポートされていません

__hash__( self)
辞書演算 の際にキーとなるオブジェクトに対して 呼び出されたり、組み込み関数 hash() から呼び出されたり します。 辞書演算におけるハッシュ値として利用できる、32 ビットの 整数を返さなければなりません。 このメソッドに必要な性質は、比較結果が等価であるオブジェクトは 同じハッシュ値をもつということです; オブジェクト間で比較を 行う際には、オブジェクトの各要素に対するハッシュ値を (排他的論理和をとるなどして) 何らかの方法で混合するよう勧めます。 クラスが __cmp__() メソッドを定義していない場合、 __hash__() メソッドも定義してはなりません; クラスが __cmp__() または __eq__() を定義しているが、 __hash__() を定義していない場合、インスタンスを 辞書のキーとして使うことはできません。 クラスが変更可能なオブジェクトを定義しており、__cmp__() または __eq__() メソッドを実装している場合、__hash__() を定義してはなりません。これは、辞書の実装においてハッシュ値が変更不能 であることが要求されているからです (オブジェクトのハッシュ値が変化 すると、キーが誤ったハッシュバケツ: hash bucket に入っていることに なってしまいます)。

__nonzero__( self)
真値テストや組み込み演算 bool() を実現するために呼び出され ます; False または True か、等価な整数値 0 または 1 を返さなければなりません。 このメソッドが定義されていない場合、__len__() (下記参照) が定義されていれば呼び出されます。__len__()__nonzero__() のどちらもクラスで定義されていない場合、 そのクラスのインスタンスはすべて真の値を持つものとみなされます。

__unicode__( self)
組み込み関数 unicode() を実現 するために呼び出されます。Unicode オブジェクトを返さなければ なりません。このメソッドが定義されていなければ、文字列への 変換が試みられ、その結果がデフォルトの文字エンコードを用いて Unicode に変換されます。

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