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

Добавлено в версии 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.

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

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

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

азбука

Наследует от

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

Способы смешивания

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__

Сноски

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

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 для итерируемых контейнерных классов определенного размера.

Добавлено в версии 3.6.

class collections.abc.Iterator

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

class collections.abc.Reversible

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

Добавлено в версии 3.6.

class collections.abc.Generator

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

Добавлено в версии 3.5.

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

Азбука только для чтения и изменяемая sequences.

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

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

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

Азбука только для чтения и изменяемая sets.

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

Азбука только для чтения и изменяемая 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() для их обнаружения.

Добавлено в версии 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() для их обнаружения.

Добавлено в версии 3.5.

class collections.abc.AsyncIterable

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

Добавлено в версии 3.5.

class collections.abc.AsyncIterator

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

Добавлено в версии 3.5.

class collections.abc.AsyncGenerator

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

Добавлено в версии 3.6.

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

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

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

Некоторые из азбук также полезны в качестве микшеров, которые упрощают разработку классов, поддерживающих контейнерные API. Например, чтобы написать класс, поддерживающий полный Set API, необходимо предоставить только три базовых абстрактных метода: __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 в качестве смесителя:

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

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

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

См.также

Вернуться на верх