# `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`, `Container` | `__contains__`, `__iter__`, `__len__` |
`Sequence` | `Reversible`, `Collection` | `__getitem__`, `__len__` | `__contains__`, `__iter__`, `__reversed__`, `index`, `count`
`MutableSequence` | `Sequence` | `__getitem__`, `__setitem__`, `__delitem__`, `__len__`, `insert` | `Sequence` から継承したメソッドと、 `append`, `clear`, `reverse`, `extend`, `pop`, `remove`, `__iadd__`
`ByteString` | `Sequence` | `__getitem__`, `__len__` | `Sequence` から継承したメソッド
`Set` | `Collection` | `__contains__`, `__iter__`, `__len__` | `__le__`, `__lt__`, `__eq__`, `__ne__`, `__gt__`, `__ge__`, `__and__`, `__or__`, `__sub__`, `__xor__`, `isdisjoint`
`MutableSet` | `Set` | `__contains__`, `__iter__`, `__len__`, `add`, `discard` | `Set` から継承したメソッドと、 `clear`, `pop`, `remove`, `__ior__`, `__iand__`, `__ixor__`, `__isub__`
`Mapping` | `Collection` | `__getitem__`, `__iter__`, `__len__` | `__contains__`, `keys`, `items`, `values`, `get`, `__eq__`, `__ne__`
`MutableMapping` | `Mapping` | `__getitem__`, `__setitem__`, `__delitem__`, `__iter__`, `__len__` | `Mapping` から継承したメソッドと、 `pop`, `popitem`, `clear`, `update`, `setdefault`
`MappingView` | `Sized` |  | `__len__`
`ItemsView` | `MappingView`, `Set` |  | `__contains__`, `__iter__`
`KeysView` | `MappingView`, `Set` |  | `__contains__`, `__iter__`
`ValuesView` | `MappingView`, `Collection` |  | `__contains__`, `__iter__`
`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] (1,2,3,4,5,6,7,8,9,10,11,12,13,14)

これらの抽象基底クラスは `__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 を参照してください。