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

Добавлено в версии 3.3: Раньше этот модуль был частью модуля collections.

Исходный код: Lib/_collections_abc.py.


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

Тест 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__(next): ...
>>> issubclass(E, Iterable)
True
>>> isinstance(E(), Iterable)
True

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

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

Эти ABC переопределяют object.__subclasshook__() для поддержки тестирования интерфейса путем проверки наличия необходимых методов, которые не были установлены в None. Это работает только для простых интерфейсов. Более сложные интерфейсы требуют регистрации или прямого подклассирования.

2

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

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

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 для классов iterable, которые также предоставляют метод __reversed__().

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

class collections.abc.Generator

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

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

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

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

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

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

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

ABC для наборов, доступных только для чтения и изменяемых.

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 coroutines на основе генераторов (генераторы, украшенные types.coroutine() или asyncio.coroutine()) являются awaitables, даже если у них нет метода __await__(). Использование isinstance(gencoro, Awaitable) для них вернет False. Для их обнаружения используйте inspect.isawaitable().

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

class collections.abc.Coroutine

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

Примечание

В CPython coroutines на основе генераторов (генераторы, украшенные types.coroutine() или asyncio.coroutine()) являются awaitables, даже если у них нет метода __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 для классов асинхронных генераторов, реализующих протокол, определенный в PEP 525 и PEP 492.

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

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

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

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

Некоторые из ABC также полезны в качестве миксинов, которые облегчают разработку классов, поддерживающих API контейнеров. Например, чтобы написать класс, поддерживающий полный API Set, необходимо предоставить только три основных абстрактных метода: __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. Поскольку некоторые операции с множествами создают новые множества, методы миксина по умолчанию нуждаются в способе создания новых экземпляров из итерабельной таблицы. Предполагается, что конструктор класса имеет сигнатуру в виде ClassName(iterable). Это предположение выводится во внутренний метод класса _from_iterable(), который вызывает cls(iterable) для создания нового множества. Если миксин Set используется в классе с другой сигнатурой конструктора, вам необходимо переопределить _from_iterable() с помощью classmethod или обычного метода, который может создавать новые экземпляры из аргумента iterable.

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

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

См.также

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