"collections.abc" --- Abstract Base Classes for Containers
**********************************************************

バージョン 3.3 で追加: 以前はこのモジュールは "collections" モジュール
の一部でした。

**ソースコード:** Lib/_collections_abc.py

======================================================================

このモジュールは、 *抽象基底クラス* を提供します。抽象基底クラスは、ク
ラスが特定のインターフェースを提供しているか、例えば *ハッシュ可能* で
あるかや *マッピング* であるかを判定します。

"issubclass()" や "isinstance()" を使ったインターフェースに対するテス
トは、以下の3つのいずれかの方法で動作します。

1） 新しく定義したクラスは抽象基底クラスのいずれかを直接継承することが
できます。その場合クラスは必要な抽象メソッドを提供しなければなりません
。残りのミックスインメソッドは継承により引き継がれますが、必要ならオー
バーライドすることができます。その他のメソッドは必要に応じて追加するこ
とができます:

   class C(Sequence):                      # Direct inheritance
       def __init__(self): ...             # Extra method not required by the ABC
       def __getitem__(self, index):  ...  # Required abstract method
       def __len__(self):  ...             # Required abstract method
       def count(self, value): ...         # Optionally override a mixin method

   >>> issubclass(C, Sequence)
   True
   >>> isinstance(C(), Sequence)
   True

2） 既存のクラスや組み込みのクラスを "仮想派生クラス" として ABC に登
録することができます。これらのクラスは、全ての抽象メソッドとミックスイ
ンメソッドを含む完全な API を定義する必要があります。これにより、その
クラスが完全なインターフェースをサポートしているかどうかを、ユーザーが
"issubclass()" や "isinstance()" で判断できるようになります。このルー
ルの例外は、残りの API から自動的に推測ができるようなメソッドです:

   class D:                                 # No inheritance
       def __init__(self): ...              # Extra method not required by the ABC
       def __getitem__(self, index):  ...   # Abstract method
       def __len__(self):  ...              # Abstract method
       def count(self, value): ...          # Mixin method
       def index(self, value): ...          # Mixin method

   Sequence.register(D)                     # Register instead of inherit

   >>> issubclass(D, Sequence)
   True
   >>> isinstance(D(), Sequence)
   True

この例では、クラス "D" は "__contains__", "__iter__", "__reversed__"
を定義する必要がありません。なぜなら in 演算子, the *反復* ロジック,
および "reversed()" 関数は自動的に "__getitem__" と "__len__" を使うよ
うにフォールバックするからです。

3） いくつかの単純なインターフェースは、必要なメソッドの存在だけで (そ
れらのメソッドが "None" に設定されていなければ) 直接認識されます:

   class E:
       def __iter__(self): ...
       def __next__(self): ...

   >>> issubclass(E, Iterable)
   True
   >>> isinstance(E(), Iterable)
   True

複雑なインターフェースは、単に特定のメソッドが存在すること以上の定義を
持つため、3番目のテクニックをサポートしていません。それらのインターフ
ェースはメソッドの意味やメソッド間の関係まで指定するので、特定のメソッ
ド名の存在からだけではインターフェースの推測ができません。たとえば、あ
るクラスが "__getitem__", "__len__", および "__iter__" を提供するとい
うだけでは、 "Sequence" と "Mapping" を区別するには不十分です。

バージョン 3.9 で追加: これらの抽象クラスは "[]" をサポートするように
なりました。 ジェネリックエイリアス型 および **PEP 585** を参照してく
ださい。


コレクション抽象基底クラス
==========================

collections モジュールは以下の *ABC (抽象基底クラス)* を提供します:

+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| ABC                            | 継承しているクラス     | 抽象メソッド            | mixin メソッド                                       |
|================================|========================|=========================|======================================================|
| "Container" [1]                |                        | "__contains__"          |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Hashable" [1]                 |                        | "__hash__"              |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Iterable" [1] [2]             |                        | "__iter__"              |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Iterator" [1]                 | "Iterable"             | "__next__"              | "__iter__"                                           |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Reversible" [1]               | "Iterable"             | "__reversed__"          |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Generator"  [1]               | "Iterator"             | "send", "throw"         | "close", "__iter__", "__next__"                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Sized"  [1]                   |                        | "__len__"               |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Callable"  [1]                |                        | "__call__"              |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Collection"  [1]              | "Sized", "Iterable",   | "__contains__",         |                                                      |
|                                | "Container"            | "__iter__", "__len__"   |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Sequence"                     | "Reversible",          | "__getitem__",          | "__contains__", "__iter__", "__reversed__", "index", |
|                                | "Collection"           | "__len__"               | "count"                                              |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "MutableSequence"              | "Sequence"             | "__getitem__",          | "Sequence" から継承したメソッドと、 "append",        |
|                                |                        | "__setitem__",          | "clear", "reverse", "extend", "pop", "remove",       |
|                                |                        | "__delitem__",          | "__iadd__"                                           |
|                                |                        | "__len__", "insert"     |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "ByteString"                   | "Sequence"             | "__getitem__",          | "Sequence" から継承したメソッド                      |
|                                |                        | "__len__"               |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Set"                          | "Collection"           | "__contains__",         | "__le__", "__lt__", "__eq__", "__ne__", "__gt__",    |
|                                |                        | "__iter__", "__len__"   | "__ge__", "__and__", "__or__", "__sub__", "__xor__", |
|                                |                        |                         | "isdisjoint"                                         |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "MutableSet"                   | "Set"                  | "__contains__",         | "Set" から継承したメソッドと、 "clear", "pop",       |
|                                |                        | "__iter__", "__len__",  | "remove", "__ior__", "__iand__", "__ixor__",         |
|                                |                        | "add", "discard"        | "__isub__"                                           |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Mapping"                      | "Collection"           | "__getitem__",          | "__contains__", "keys", "items", "values", "get",    |
|                                |                        | "__iter__", "__len__"   | "__eq__", "__ne__"                                   |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "MutableMapping"               | "Mapping"              | "__getitem__",          | "Mapping" から継承したメソッドと、 "pop", "popitem", |
|                                |                        | "__setitem__",          | "clear", "update", "setdefault"                      |
|                                |                        | "__delitem__",          |                                                      |
|                                |                        | "__iter__", "__len__"   |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "MappingView"                  | "Sized"                |                         | "__len__"                                            |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "ItemsView"                    | "MappingView", "Set"   |                         | "__contains__", "__iter__"                           |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "KeysView"                     | "MappingView", "Set"   |                         | "__contains__", "__iter__"                           |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "ValuesView"                   | "MappingView",         |                         | "__contains__", "__iter__"                           |
|                                | "Collection"           |                         |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Awaitable" [1]                |                        | "__await__"             |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Coroutine" [1]                | "Awaitable"            | "send", "throw"         | "close"                                              |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "AsyncIterable" [1]            |                        | "__aiter__"             |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "AsyncIterator" [1]            | "AsyncIterable"        | "__anext__"             | "__aiter__"                                          |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "AsyncGenerator" [1]           | "AsyncIterator"        | "asend", "athrow"       | "aclose", "__aiter__", "__anext__"                   |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+

-[ 脚注 ]-

[1] これらの抽象基底クラスは "__subclasshook__()" をオーバーライドして
    、必要なメソッドが存在し、かつ "None" に指定されていないことを確か
    めることによってインターフェースをテストすることをサポートします。
    このテストは単純なインターフェースに対してのみ有効に働きます。より
    複雑なインターフェースは基底クラスへの登録や直接派生することが必要
    になります。

[2] "isinstance(obj, Iterable)" によるチェックは "Iterable" として登録
    されたクラスや "__iter__()" メソッドを持つクラスを検出しますが、
    "__getitem__()" メソッドにより反復処理を行うクラスは検出しません。
    オブジェクトがイテラブル (*iterable*) かどうかを確認する唯一の信頼
    できる方法は "iter(obj)" を呼び出すことです。


コレクションの抽象基底クラス -- 詳細な説明
==========================================

class collections.abc.Container

   "__contains__()" メソッドを提供するクラスの ABC です。

class collections.abc.Hashable

   "__hash__()" メソッドを提供するクラスの ABC です。

class collections.abc.Sized

   "__len__()" メソッドを提供するクラスの ABC です。

class collections.abc.Callable

   "__call__()" メソッドを提供するクラスの ABC です。

class collections.abc.Iterable

   "__iter__()" メソッドを提供するクラスの ABC です。

   "isinstance(obj, Iterable)" によるチェックは "Iterable" として登録
   されたクラスや "__iter__()" メソッドを持つクラスを検出しますが、
   "__getitem__()" メソッドにより反復処理を行うクラスは検出しません。
   オブジェクトがイテラブル (*iterable*) かどうかを確認する唯一の信頼
   できる方法は "iter(obj)" を呼び出すことです。

class collections.abc.Collection

   サイズ付きのイテラブルなコンテナクラスの ABC です。

   バージョン 3.6 で追加.

class collections.abc.Iterator

   "__iter__()" メソッドと "__next__()" メソッドを提供するクラスの ABC
   です。 *iterator* の定義も参照してください。

class collections.abc.Reversible

   "__reversed__()" メソッドを提供するイテラブルクラスの ABC です。

   バージョン 3.6 で追加.

class collections.abc.Generator

   **PEP 342** で定義された、*イテレータ* を "send()", "throw()",
   "close()" の各メソッドに拡張するプロトコルを実装する、*ジェネレータ
   * クラスの ABC です。

   バージョン 3.5 で追加.

class collections.abc.Sequence
class collections.abc.MutableSequence
class collections.abc.ByteString

   読み出し専用の *シーケンス* およびミュータブルな *シーケンス* の
   ABC です。

   実装における注意: "__iter__()", "__reversed__()", "index()" など、
   一部の mixin メソッドは、下層の "__getitem__()" メソッドを繰り返し
   呼び出します。その結果、"__getitem__()" が定数のアクセス速度で実装
   されている場合、mixin メソッドは線形のパフォーマンスとなります。下
   層のメソッドが線形 (リンクされたリストの場合など) の場合、mixin は
   2 乗のパフォーマンスとなるため、多くの場合上書きする必要があるでし
   ょう。

   バージョン 3.5 で変更: index() メソッドは *stop* と *start* 引数を
   サポートしました。

class collections.abc.Set
class collections.abc.MutableSet

   読み出し専用でミュータブルな 集合 の ABC です。

class collections.abc.Mapping
class collections.abc.MutableMapping

   読み出し専用の *マッピング* およびミュータブルな *マッピング* の
   ABC です。

class collections.abc.MappingView
class collections.abc.ItemsView
class collections.abc.KeysView
class collections.abc.ValuesView

   マッピング、要素、キー、値の *ビュー* の ABC です。

class collections.abc.Awaitable

   "await" で使用できる *awaitable* オブジェクトの ABC です。カスタム
   の実装は、"__await__()" メソッドを提供しなければなりません。

   "Coroutine" ABC の *Coroutine* オブジェクトとインスタンスは、すべて
   この ABC のインスタンスです。

   注釈:

     CPython では、ジェネレータベースのコルーチン ("@types.coroutine"
     で修飾された *ジェネレータ*) は、 "__await__()" メソッドを持たな
     いにもかかわらず*待機可能* (*awaitables*) です。
     "isinstance(gencoro, Awaitable)" はそのようなコルーチンに対して
     "False" を返します。そのようなコルーチンを検出するためには
     "inspect.isawaitable()" を使ってください。

   バージョン 3.5 で追加.

class collections.abc.Coroutine

   *コルーチン* と互換性のあるクラスの ABC です。これらは、コルーチン
   オブジェクト で定義された "send()", "throw()", "close()" のメソッド
   を実装します。カスタムの実装は、"__await__()" も実装しなければなり
   ません。"Coroutine" のすべてのインスタンスは、 "Awaitable" のインス
   タンスでもあります。

   注釈:

     CPython では、ジェネレータベースのコルーチン ("@types.coroutine"
     で修飾された *ジェネレータ*) は、 "__await__()" メソッドを持たな
     いにもかかわらず*待機可能* (*awaitables*) です。
     "isinstance(gencoro, Coroutine)" はそのようなコルーチンに対して
     "False" を返します。そのようなコルーチンを検出するためには
     "inspect.isawaitable()" を使ってください。

   バージョン 3.5 で追加.

class collections.abc.AsyncIterable

   "__aiter__" メソッドを提供するクラスの ABC です。*asynchronous
   iterable* の定義も参照してください。

   バージョン 3.5 で追加.

class collections.abc.AsyncIterator

   "__aiter__" および "__anext__" メソッドを提供するクラスの ABC です
   。*asynchronous iterator* の定義も参照してください。

   バージョン 3.5 で追加.

class collections.abc.AsyncGenerator

   **PEP 525** と **PEP 492** に定義されているプロトコルを実装した *非
   同期ジェネレータ*  クラスの ABC です。

   バージョン 3.6 で追加.


例とレシピ
==========

抽象基底クラスは、クラスやインスタンスが特定の機能を提供しているかどう
かを調べることを可能にします。例えば:

   size = None
   if isinstance(myvar, collections.abc.Sized):
       size = len(myvar)

幾つかの ABC はコンテナ型 API を提供するクラスを開発するのを助ける
mixin 型としても使えます。例えば、 "Set" API を提供するクラスを作る場
合、3つの基本になる抽象メソッド "__contains__()", "__iter__()",
"__len__()" だけが必要です。ABC が残りの "__and__()" や "isdisjoint()"
といったメソッドを提供します:

   class ListBasedSet(collections.abc.Set):
       ''' Alternate set implementation favoring space over speed
           and not requiring the set elements to be hashable. '''
       def __init__(self, iterable):
           self.elements = lst = []
           for value in iterable:
               if value not in lst:
                   lst.append(value)

       def __iter__(self):
           return iter(self.elements)

       def __contains__(self, value):
           return value in self.elements

       def __len__(self):
           return len(self.elements)

   s1 = ListBasedSet('abcdef')
   s2 = ListBasedSet('defghi')
   overlap = s1 & s2            # The __and__() method is supported automatically

"Set" と "MutableSet" を mixin 型として利用するときの注意点:

1. 幾つかの set の操作は新しい set を作るので、デフォルトの mixin メソ
   ッドは *イテラブル* から新しいインスタンスを作成する方法を必要とし
   ます。クラスのコンストラクタは "ClassName(iterable)" の形のシグネチ
   ャを持つと仮定されます。内部の "_from_iterable()" という
   "classmethod" が "cls(iterable)" を呼び出して新しい set を作る部分
   でこの仮定が使われています。コンストラクタのシグネチャが異なるクラ
   スで "Set" を使う場合は、 iterable 引数から新しいインスタンスを生成
   できるクラスメソッドあるいは仕様に沿ったメソッドで
   "_from_iterable()" をオーバーライドする必要があります。

2. (たぶん意味はそのままに速度を向上する目的で)比較をオーバーライドす
   る場合、 "__le__()" と "__ge__()" だけを再定義すれば、その他の演算
   は自動的に追随します。

3. "Set" mixin型は set のハッシュ値を計算する "_hash()" メソッドを提供
   しますが、すべての set が *hashable* や immutable とは限らないので
   、 "__hash__()" は提供しません。 mixin を使ってハッシュ可能な set
   を作る場合は、 "Set" と "Hashable()" の両方を継承して、 "__hash__ =
   Set._hash" と定義してください。

参考:

  * "MutableSet" を使った例として OrderedSet recipe。

  * ABCs についての詳細は、 "abc" モジュールと **PEP 3119** を参照して
    ください。
