Документация Python неофициальный перевод
Содержание страницы

collections.abc – Абстрактные базовые классы для контейнеровcollections.abc – Abstract Base Classes for Containers

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

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


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

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

1) Недавно написанный класс может наследовать напрямую от одного из абстрактных базовых классов. Класс должен предоставлять требуемые абстрактные методы. Остальные методы-примеси достаются по наследству и могут быть переопределены при необходимости. Другие методы можно добавлять по мере необходимости:

class C(Sequence):                      # Прямое наследование
    def __init__(self): ...             # Дополнительный метод, не требуемый ABC
    def __getitem__(self, index):  ...  # Обязательный абстрактный метод
    def __len__(self):  ...             # Обязательный абстрактный метод
    def count(self, value): ...         # Необязательное переопределение метода-примеси
>>> issubclass(C, Sequence)
True
>>> isinstance(C(), Sequence)
True

2) Существующие и встроенные классы могут быть зарегистрированы как «виртуальные подклассы» ABC. Такие классы должны определять полный API, включая все абстрактные методы и все методы-примеси. Это позволяет пользователям полагаться на проверки issubclass() или isinstance(), чтобы определить, поддерживается ли полный интерфейс. Исключение из этого правила составляют методы, которые автоматически выводятся из остального API:

class D:                                 # Нет наследования
    def __init__(self): ...              # Дополнительный метод, не требуемый ABC
    def __getitem__(self, index):  ...   # Обязательный абстрактный метод
    def __len__(self):  ...              # Обязательный абстрактный метод
    def count(self, value): ...          # Метод-примесь
    def index(self, value): ...          # Метод-примесь

Sequence.register(D)                     # Регистрация вместо наследования
>>> issubclass(D, Sequence)
True
>>> isinstance(D(), Sequence)
True

В этом примере классу D не нужно определять __contains__, __iter__ и __reversed__, потому что оператор in, логика итерации и функция reversed() автоматически используют __getitem__ и __len__.

3) Некоторые простые интерфейсы распознаются напрямую по наличию требуемых методов (если только эти методы не были установлены в None):

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

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

Новинка версии 3.9: Эти абстрактные классы теперь поддерживают []. См. Generic Alias Type и PEP 585.

Абстрактные базовые классы коллекцийCollections Abstract Base Classes

Модуль collections предоставляет следующие абстрактные базовые классы:

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__(). Единственный надёжный способ определить, является ли объект итерируемым – вызвать iter(obj).

Абстрактные базовые классы коллекций – Подробные описанияCollections Abstract Base Classes – Detailed Descriptions

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__(). Единственный надёжный способ определить, является ли объект итерируемым, – вызвать iter(obj).

class collections.abc.Collection

ABC для классов-контейнеров, которые поддерживают итерирование и определение размера.

Новое в версии 3.6.

class collections.abc.Iterator

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

class collections.abc.Reversible

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

Новое в версии 3.6.

class collections.abc.Generator

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

Новое в версии 3.5.

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

ABC для неизменяемых и изменяемых последовательностей.

Примечание к реализации: некоторые методы-примеси, такие как __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

ABC для неизменяемых и изменяемых отображений.

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

ABC для представлений отображений, элементов, ключей и значений.

class collections.abc.Awaitable

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

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

Примечание

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

Новое в версии 3.5.

class collections.abc.Coroutine

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

Примечание

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

Новое в версии 3.5.

class collections.abc.AsyncIterable

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

Новое в версии 3.5.

class collections.abc.AsyncIterator

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

Новое в версии 3.5.

class collections.abc.AsyncGenerator

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

Новое в версии 3.6.

Примеры и рецептыExamples and Recipes

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

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

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

class ListBasedSet(collections.abc.Set):
    ''' Альтернативная реализация множества, ориентированная на экономию памяти, а не на скорость
        и не требующая, чтобы элементы множества были хэшируемыми. '''
    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            # Метод __and__() поддерживается автоматически

Замечания по использованию Set и MutableSet в качестве примеси:

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

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

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

См. также

  • Рецепт OrderedSet для примера, построенного на MutableSet.

  • Для получения дополнительной информации об ABC см. модуль abc и .