collections.abc — Абстрактные базовые классы для контейнеров

Added in version 3.3: Раньше этот модуль был частью модуля collections.

Источник: Lib/_collections_abc.py


Этот модуль предоставляет abstract base classes, который можно использовать для проверки того, предоставляет ли класс определенный интерфейс; например, является ли он hashable или mapping.

Тест issubclass() или isinstance() для интерфейса работает одним из трех способов.

1) A newly written class can inherit directly from one of the abstract base classes. The class must supply the required abstract methods. The remaining mixin methods come from inheritance and can be overridden if desired. Other methods may be added as needed:

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) Existing classes and built-in classes can be registered as «virtual subclasses» of the ABCs. Those classes should define the full API including all of the abstract methods and all of the mixin methods. This lets users rely on issubclass() or isinstance() tests to determine whether the full interface is supported. The exception to this rule is for methods that are automatically inferred from the rest of the 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-operator, iteration и функция reversed() автоматически возвращаются к использованию __getitem__ и __len__.

3) Some simple interfaces are directly recognizable by the presence of the required methods (unless those methods have been set to None):

class E:
    def __iter__(self): ...
    def __next__(self): ...
>>> issubclass(E, Iterable)
True
>>> isinstance(E(), Iterable)
True

Сложные интерфейсы не поддерживают эту последнюю технику, потому что интерфейс - это нечто большее, чем просто наличие имен методов. Интерфейсы определяют семантику и отношения между методами, которые нельзя вывести только из наличия конкретных имен методов. Например, знание того, что класс предоставляет __getitem__, __len__ и __iter__, недостаточно для того, чтобы отличить Sequence от Mapping.

Added in version 3.9: Эти абстрактные классы теперь поддерживают []. См. Общий тип псевдонима и PEP 585.

Коллекции Абстрактные базовые классы

Модуль коллекций предлагает следующие ABCs:

ABC

Наследует от

Абстрактные методы

Методы миксинов

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__.

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__

Buffer [1]

__buffer__

Сноски

Абстрактные базовые классы коллекций - подробные описания

class collections.abc.Container

ABC для классов, предоставляющих метод __contains__().

class collections.abc.Hashable

ABC для классов, предоставляющих метод __hash__().

class collections.abc.Sized

ABC для классов, предоставляющих метод __len__().

class collections.abc.Callable

ABC для классов, предоставляющих метод __call__().

class collections.abc.Iterable

ABC для классов, предоставляющих метод __iter__().

Проверка isinstance(obj, Iterable) обнаруживает классы, зарегистрированные как Iterable или имеющие метод __iter__(), но не обнаруживает классы, которые выполняют итерацию с помощью метода __getitem__(). Единственный надежный способ определить, является ли объект iterable, - вызвать iter(obj).

class collections.abc.Collection

ABC для классов контейнеров с итерируемыми размерами.

Added in version 3.6.

class collections.abc.Iterator

ABC для классов, предоставляющих методы __iter__() и __next__(). См. также определение iterator.

class collections.abc.Reversible

ABC для классов iterable, которые также предоставляют метод __reversed__().

Added in version 3.6.

class collections.abc.Generator

ABC для классов generator, реализующих протокол, определенный в PEP 342, который расширяет iterators с помощью методов send(), throw() и close().

Added in version 3.5.

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

ABC для доступных только для чтения и изменяемых sequences.

Примечание по реализации: Некоторые из методов миксинов, такие как __iter__(), __reversed__() и index(), выполняют повторные обращения к базовому методу __getitem__(). Следовательно, если __getitem__() реализован с постоянной скоростью доступа, методы миксинов будут иметь линейную производительность; однако если базовый метод линейный (как в случае со связным списком), миксины будут иметь квадратичную производительность и, скорее всего, потребуют переопределения.

Изменено в версии 3.5: В метод index() добавлена поддержка аргументов stop и start.

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

ABC для доступных только для чтения и изменяемых sets.

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

ABC для доступных только для чтения и изменяемых mappings.

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

Азбука отображения, элементов, ключей и значений views.

class collections.abc.Awaitable

ABC для объектов awaitable, которые могут быть использованы в выражениях await. Пользовательские реализации должны предоставлять метод __await__().

Объекты Coroutine и экземпляры Coroutine ABC - это все экземпляры этого ABC.

Примечание

В CPython корутины на основе генератора (generators, украшенные @types.coroutine) являются дожидающимися, даже если у них нет метода __await__(). Использование isinstance(gencoro, Awaitable) для них вернет False. Для их обнаружения используйте inspect.isawaitable().

Added in version 3.5.

class collections.abc.Coroutine

ABC для классов, совместимых с coroutine. Они реализуют следующие методы, определенные в Объекты корутины: send(), throw() и close(). Пользовательские реализации должны также реализовывать __await__(). Все экземпляры Coroutine также являются экземплярами Awaitable.

Примечание

В CPython корутины на основе генератора (generators, украшенные @types.coroutine) являются дожидающимися, даже если у них нет метода __await__(). Использование isinstance(gencoro, Coroutine) для них вернет False. Для их обнаружения используйте inspect.isawaitable().

Added in version 3.5.

class collections.abc.AsyncIterable

ABC для классов, предоставляющих метод __aiter__. См. также определение asynchronous iterable.

Added in version 3.5.

class collections.abc.AsyncIterator

ABC для классов, предоставляющих методы __aiter__ и __anext__. См. также определение asynchronous iterator.

Added in version 3.5.

class collections.abc.AsyncGenerator

ABC для классов asynchronous generator, реализующих протокол, определенный в PEP 525 и PEP 492.

Added in version 3.6.

class collections.abc.Buffer

ABC для классов, которые предоставляют метод __buffer__(), реализуя buffer protocol. См. PEP 688.

Added in version 3.12.

Примеры и рецепты

ABC позволяют нам спрашивать классы или экземпляры, предоставляют ли они определенную функциональность, например:

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

Некоторые из ABC также полезны в качестве миксинов, которые облегчают разработку классов, поддерживающих контейнерные API. Например, чтобы написать класс, поддерживающий полный Set API, необходимо предоставить только три базовых абстрактных метода: __contains__(), __iter__() и __len__(). Остальные методы, такие как __and__() и isdisjoint(), предоставляет ABC:

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 в качестве миксина:

  1. Поскольку некоторые операции с множествами создают новые множества, методам миксина по умолчанию необходим способ создания новых экземпляров из iterable. Предполагается, что конструктор класса имеет сигнатуру в виде ClassName(iterable). Это предположение раскладывается на внутренний classmethod, называемый _from_iterable(), который вызывает cls(iterable) для создания нового набора. Если миксин Set используется в классе с другой сигнатурой конструктора, вам нужно переопределить _from_iterable() с помощью метода класса или обычного метода, который может создавать новые экземпляры из аргумента iterable.

  2. Чтобы отменить сравнения (предположительно для скорости, поскольку семантика фиксирована), переопределите __le__() и __ge__(), тогда остальные операции автоматически последуют за ними.

  3. Миксин Set предоставляет метод _hash() для вычисления хэш-значения для набора; однако __hash__() не определен, поскольку не все наборы являются hashable или неизменяемыми. Чтобы добавить хэшируемость множества с помощью миксинов, наследуйте от Set() и Hashable(), а затем определите __hash__ = Set._hash.

См.также