# `collections.abc` --- コレクションの抽象基底クラス

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

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

This module provides abstract base classes that can be used to test whether a class provides a particular interface; for example, whether it is hashable or whether it is a mapping.

`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__(next): ...

    >>> 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`, `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)

  これらの抽象基底クラスは `object.__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 です。generator の定義も参照してください。

  バージョン 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()` または `asyncio.coroutine()` でデコレートされたジェネレータ) は、 `__await__()` メソッドを持ちませんが、待機可能 (awaitables) です。これらに対して `isinstance(gencoro, Awaitable)` を使用すると、 `False` が返されます。これらを検出するには、 `inspect.isawaitable()` を使用します。

  バージョン 3.5 で追加.

class `collections.abc.``Coroutine`

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

  注釈

  CPython では、ジェネレータベースのコルーチン (`types.coroutine()` または `asyncio.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 メソッドは iterable から新しいインスタンスを作成する方法を必要とします。クラスのコンストラクタは `ClassName(iterable)` の形のシグネチャを持つと仮定されます。内部の `_from_iterable()` というクラスメソッドが `cls(iterable)` を呼び出して新しい set を作る部分でこの仮定が使われています。コンストラクタのシグネチャが異なるクラスで `Set` を使う場合は、 iterable 引数から新しいインスタンスを生成できるクラスメソッドあるいは仕様に沿ったメソッドで `_from_iterable()` をオーバーライドする必要があります。

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

3. The `Set` mixin provides a `_hash()` method to compute a hash value for the set; however, `__hash__()` is not defined because not all sets are hashable or immutable. To add set hashability using mixins, inherit from both `Set()` and `Hashable()`, then define `__hash__ = Set._hash`.

参考

- `MutableSet` を使った例として OrderedSet recipe。

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