##
3.3.8 型強制規則 (coercion rule)

本節では、型強制 (coercion) に関する規則について記述します。 プログラム言語が進化するにつれ、型強制規則について正確に 記述するのは難しくなってゆきます; 従って、あるバージョンのある 実装について記述するのは望ましくありません。その代わりに、 型強制に関する非公式的なガイドラインを示しておきます。 Python 3.0 からは、型強制がサポートされなくなる予定です。

- % 演算子の左被演算子が文字列か Unicode オブジェクトの場合、 型強制は起きず、文字列としての書式化操作が呼び出されます。

- 型強制演算の定義はもはや推奨されていません。 型強制を定義していない混合型 (mixed-mode) 演算は、 もとの引数をそのまま演算操作に渡すようになっています。

- 新しい形式のクラス (`object` から導出されたもの) が、 二項演算子に対して `__coerce__()` メソッドを呼び出すことは ありません。; `__coerce__()` が呼び出されるのは、組み込み 関数 `coerce()` が呼び出されたときだけです。

- 事実上、 `NotImplemented` を返す演算子は、全く実装されていないも のとして扱われます。

- 以下の説明では、`__op__()` および `__rop__()` は、演算子 に相当する一般的なメソッド名を表すために使われます; `__iop__` はインプレース演算子を表します。例えば、演算子 ``+`' の場合、 `__add__()` および `__radd__()` がそれぞれ左右の被演算子 用の二項演算子として使われ、`__iadd__` がインプレース演算用の演 算子として使われる、といった具合です。

- オブジェクト x および y に対して、 まず `x.__op__(y)` が試されます。この演算が実装されて いないか、`NotImplemented` を返す場合、次に `y.__rop__(x)` が試されます。この演算も実装されていな いか、`NotImplemented` を返すなら、 `TypeError` 例外が送出されます。ただし、以下の例外があるので参照してください:

- 前項に対する例外: 左被演算子が組み込み型や新形式クラスのインスタンスで あり、かつ右被演算子が左被演算子と同じクラスか適切なサブクラスのインス タンスである場合、左被演算子の `__op__()` メソッドを試す 前に 右被演算子の `__rop__()` が試されます。 これは、サブクラス側で二項演算子を完全にオーバライドできるようにするた めです。そうしなければ、常に左被演算子の __op__ メソッドが右被演算子を 受理してしまいます: あるクラスのインスタンスが被演算子になるとされてい る場合、そのサブクラスのインスタンスもまた受理可能だからです。

- 双方の被演算子が型強制を定義している場合、型強制は被演算子の型の `__op__()` や `__rop__()` メソッドが呼び出される前に呼 び出され、それより早くなることはありません。型強制の結果、型強制を行う ことになったいずれの被演算子とも異なる型が返された場合、返されたオブジェ クトの新たな型を使って、この過程が部分的に再度行われます。

- (``+=`' のような) インプレース型の演算子を用いる際、左被演算子が `__iop__()` を実装していれば、`__iop__()` が呼び出され、 方強制は一切行われません。演算が `__op__()` かつ/または `__rop__()` に帰着した場合、通常の型強制規則が適用されます。

- x`+`y において、 x が結合 (concatenation) 演算 を実装している配列であれば、配列の結合が実行されます。

- x`*`y において、一方の演算子が繰り返し (repeat) 演算 を実装している配列であり、かつ他方が整数 (`int` または `long`) である場合、配列の繰り返しが実行されます。

- (`__eq__()` などのメソッドで実装されている) 拡張比較は、決して 型強制を行いません。(`__cmp__()` で実装されている) 三値比較 (three-way comparison) は、他の二項演算子で行われているのと同じ条件で 型強制を受けます。

- 現在の実装では、組み込み数値型 `int`, `long` および `float` は型強制を行いません; 一方、`complex` は型強制 を使います。こうした違いは、これらの型をサブクラス化する際に顕在化して きます。そのうち、 `complex` 型についても型強制を避けるよう修正 されるかもしれません。これらの型は全て、関数 `coerce()` から 利用するための `__coerce__()` メソッドを実装しています。