##
3.3.5 コンテナをエミュレートする

以下のメソッドを定義して、コンテナオブジェクトを実装することができます。 コンテナは通常、(リストやタプルのような) 配列や、(辞書のような) マップ型を指しますが、他のコンテナも同じように表現することができます。 最初の一連のメソッドは、配列をエミュレートしたり、マップ型を エミュレートするために使われます; その違いとして、配列の場合には、 キーとして許されているのが、配列の長さが N であるときの `0 <= k < N` なる整数 k か、あるいは 要素の範囲を表すスライスオブジェクトでなければならないということです。 (後方互換性のため、`__getslice__()` (以下参照) を 定義して、拡張されていない単純なスライスを扱うようにもできます。) 変更可能な配列では、Python の標準リストオブジェクトのように、 メソッド `append()`、 `count()`、 `index()`、`extend()`、`insert()`、 `pop()`、 `remove()`、`reverse()`、および`sort()` を 提供しなければなりません。 マップ型でも、Python の標準辞書オブジェクトのように、 `keys()`、 `values()`、 `items()`、 `has_key()`、 `get()`、 `clear()`、 `setdefault()`、`iterkeys()`、 `itervalues()`、 `iteritems()`、 `pop()`、 `popitem()`、 `copy()`、 および `update()` といったメソッドをマップ型 で提供するよう推奨しています。`UserDict` モジュールでは、 これらのメソッドを`__getitem__()`、 `__setitem__()`、 `__delitem__()`、および `keys()` といった基本セットから 作成する上で役に立つ `DictMixin` クラスを提供しています。 最後に、配列型では以下に述べるメソッド群 `__add__()`、 `__radd__()`、 `__iadd__()`、`__mul__()`、 `__rmul__()`、および `__imul__()` を定義して、 (配列間の結合を意味する) 加算操作と (要素の繰り返しを 意味する) 乗算操作を実装しなければなりません; `__coerce__()` や、その他の数値演算子を定義してはなりません。 マップでも配列でも、`in` 演算子が有効利用できるように `__contains__()` メソッドの定義を推奨します; マップ型では、 `in` は`has_key()` と等価でなければなりません; 配列では、 配列内の値にわたって検索を行わなければなりません。さらに、 マップでも配列でも、コンテナ内にわたる反復操作ができるようにするため、 `__iter__()` を実装するよう勧めます; マップ型の場合、 `__iter__()` は `iterkeys()` と等価でなければなりません; 配列の場合、配列内の値にわたって反復操作を行わなければなりません。

`__len__`( | self)

  組み込み関数 `len()` を実現するために 呼び出されます。オブジェクトの長さを `>=` 0 である整数で 返さなければなりません。また、オブジェクトが `__nonzero__()` メソッドを定義しておらず、`__len__()` メソッドがゼロを 返す場合には、ブール演算コンテキストでは偽であるとみなされます。

`__getitem__`( | self, key)

  `self[key]` の値評価 (evaluation) を実現するために 呼び出されます。 配列の場合、キーとして整数とスライスオブジェクトを受理できなければ なりません。 (配列型をエミュレートする場合) 負のインデクスの解釈は `__getitem__()` メソッド次第と なります。key が不適切な型であった場合、`TypeError` を送出してもかまいません; (負のインデクス値に対して何らかの解釈 を行った上で) key が配列のインデクス集合外の値である場合、 `IndexError` を送出しなければなりません。 注意: `for` ループでは、配列の終端を正しく検出できるように するために、不正なインデクスに対して `IndexError` が送出されるものと期待しています。

`__setitem__`( | self, key, value)

  `self[key]` に対する代入を実現するために呼び出されます。 `__getitem__()` と同じ注意事項があてはまります。 このメソッドを実装できるのは、あるキーに対する値の変更をサポートしているか、 新たなキーを追加できるようなマップの場合と、ある要素を置き換えることができる 配列の場合だけです。不正な key に対しては、`__getitem__()` メソッドと同様の例外の送出を行わなければなりません。

`__delitem__`( | self, key)

  `self[key]` の削除を実現するために呼び出されます。 `__getitem__()` と同じ注意事項があてはまります。 このメソッドを実装できるのは、キーの削除をサポートしているマップの場合と、 要素を削除できる配列の場合だけです。 不正な key に対しては、`__getitem__()` メソッドと同様の例外の送出を行わなければなりません。

`__iter__`( | self)

  このメソッドは、コンテナに対してイテレータが要求された際に呼び出されます。 このメソッドは、コンテナ内の全てのオブジェクトにわたる反復処理ができる ような、新たなイテレータオブジェクトを返さなければなりません。 マップの場合、コンテナ内のキーに渡る反復処理でなければならず、 かつ`iterkeys()` によって利用できなければなりません。

  イテレータオブジェクトでもこのメソッドを実装する必要があります; イテレータの場合、自分自身を返さなければなりません。イテレータオブジェクト に関するより詳細な情報は、 Python ライブラリリファレンス の ``イテレータ型'' を参照してください。

メンバシップテスト演算子 (`in` および `not in`) は通常、 配列に渡る反復処理を使って実装されます。しかし、コンテナオブジェクト で以下の特殊メソッドを定義して、より効率的な実装を行ったり、オブジェクト が配列でなくてもよいようにできます。

`__contains__`( | self, item)

  メンバシップテスト演算を実現するために呼び出されます。 item が self 内に存在する場合には真を、そうでない場合には 偽を返さなければなりません。マップオブジェクトの場合、値やキーと値の 組ではなく、キーに対するメンバシップテストを考えなければなりません。