Перейти к содержимому

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

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

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


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

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

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

    python
    class C(Sequence):                      # Необязательно переопределять метод примеси
        def __init__(self): ...             # Без наследования
        def __getitem__(self, index):  ...  # Абстрактный метод
        def __len__(self):  ...             # Абстрактный метод
        def count(self, value): ...         # Метод примеси
    
    python
    >>> issubclass(C, Sequence)
    True
    >>> isinstance(C(), Sequence)
    True
    
  2. Существующие классы и встроенные классы могут быть зарегистрированы как «виртуальные подклассы» ABC. Эти классы должны определять полный API, включая все абстрактные методы и все методы-примеси. Это позволяет пользователям полагаться на проверки issubclass() или isinstance(), чтобы определить, поддерживается ли полный интерфейс. Исключением из этого правила являются методы, которые автоматически выводятся из остальной части API:

    python
    class D:                                 # Регистрация вместо наследования
        def __init__(self): ...              # Без наследования
        def __getitem__(self, index):  ...   # Абстрактный метод
        def __len__(self):  ...              # Абстрактный метод
        def count(self, value): ...          # Метод-примесь
        def index(self, value): ...          # Метод-примесь
    
    Sequence.register(D)                     # Регистрация вместо наследования
    
    python
    >>> issubclass(D, Sequence)
    True
    >>> isinstance(D(), Sequence)
    True
    

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

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

    python
    class E:
        def __iter__(self): ...
        def __next__(self): ...
    
    python
    >>> 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:

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__

ByteString

Sequence

__getitem__, __len__

Унаследованные методы Sequence

Set

Collection

__contains__, __iter__, __len__

__le__, __lt__, __eq__, __ne__, __gt__, __ge__, __and__, __or__, __sub__, __rsub__, __xor__, __rxor__ и 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

__init__, __len__ и __repr__

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__

Сноски

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

См. Аннотирование вызываемых объектов для получения подробной информации о том, как использовать Callable в аннотациях типов.

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().

См. Аннотирование генераторов и корутин для подробностей об использовании Generator в аннотациях типов.

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

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

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

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

index(value, start=0, stop=None)

Возвращает первый индекс значения.

Возбуждает ValueError, если значение отсутствует.

Поддержка аргументов начало и конец является необязательной, но рекомендуется.

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

Устарело с версии 3.12, будет удалено в версии 3.17: Абстрактный базовый класс ByteString устарел.

Используйте isinstance(obj, collections.abc.Buffer), чтобы проверить, реализует ли obj протокол буфера во время выполнения. Для использования в аннотациях типов используйте Buffer или объединение, которое явно указывает типы, поддерживаемые вашим кодом (например, bytes | bytearray | memoryview).

ByteString изначально задумывался как абстрактный класс, который служил бы супертипом как для bytes, так и для bytearray. Однако, поскольку ABC никогда не имел никаких методов, знание того, что объект является экземпляром ByteString, никогда не давало никакой полезной информации об объекте. Другие распространённые типы буферов, такие как memoryview, также никогда не рассматривались как подтипы ByteString (ни во время выполнения, ни статическими проверками типов).

См. PEP 688 для получения более подробной информации.

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

Абстрактные базовые классы для неизменяемых и изменяемых множеств.

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

Абстрактные базовые классы для неизменяемых и изменяемых отображений.

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

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

class collections.abc.Awaitable

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

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

Примечание

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

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

class collections.abc.Coroutine

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

Примечание

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

См. Annotating generators and coroutines для подробностей об использовании Coroutine в аннотациях типов. Вариантность и порядок параметров типа соответствуют таковым у Generator.

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

class collections.abc.AsyncIterable

Абстрактный базовый класс для классов, предоставляющих метод __aiter__. См. также определение асинхронного итерируемого объекта.

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

class collections.abc.AsyncIterator

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

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

class collections.abc.AsyncGenerator

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

См. Аннотирование генераторов и корутин для подробностей об использовании AsyncGenerator в аннотациях типов.

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

class collections.abc.Buffer

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

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

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

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

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

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

python
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            # Метод __and__() поддерживается автоматически

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

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

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

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

Смотрите также