Spec-Zone.ru › Python 3.14

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

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

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

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

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

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

    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. Существующие классы и встроенные классы можно зарегистрировать как «виртуальные подклассы» ABC. Такие классы должны определять полный API, включая все абстрактные методы и методы-миксины. Это позволяет пользователям полагаться на проверки с помощью issubclass() или isinstance(), чтобы определить, поддерживается ли полный интерфейс. Исключение из этого правила составляют методы, которые автоматически выводятся из остальной части 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, логика итерации и функция reversed() автоматически используют __getitem__ и __len__ в качестве запасного варианта.

  3. Некоторые простые интерфейсы можно распознать непосредственно по наличию требуемых методов (если только для этих методов не задано значение 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.

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

Модуль 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__

Примечания

[1] (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)

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

[2]

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

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

class collections.abc.Container

Абстрактный базовый класс для классов, предоставляющих метод __contains__().

class collections.abc.Hashable

Абстрактный базовый класс для классов, предоставляющих метод __hash__().

class collections.abc.Sized

Абстрактный базовый класс для классов, предоставляющих метод __len__().

class collections.abc.Callable

Абстрактный базовый класс для классов, предоставляющих метод __call__().

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

class collections.abc.Iterable

Абстрактный базовый класс для классов, предоставляющих метод __iter__().

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

class collections.abc.Collection

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

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

class collections.abc.Iterator

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

class collections.abc.Reversible

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

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

class collections.abc.Generator

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

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

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

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

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

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

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

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

Вызывает исключение ValueError, если значение отсутствует.

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

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

Устарело начиная с версии 3.12; будет удалено в версии 3.17: Абстрактный базовый класс ByteString объявлен устаревшим.

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

Изначально ByteString задумывался как абстрактный класс, который служил бы супертипом для bytes и bytearray. Однако у этого абстрактного базового класса никогда не было методов, поэтому знание о том, что объект является экземпляром 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__().

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

Примечание

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

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

class collections.abc.Coroutine

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

Примечание

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

Подробную информацию об использовании Coroutine в аннотациях типов см. в разделе Аннотирование генераторов и сопрограмм. Ковариантность и порядок параметров типов соответствуют параметрам Generator.

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

class collections.abc.AsyncIterable

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

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

class collections.abc.AsyncIterator

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

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

class collections.abc.AsyncGenerator

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

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

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

class collections.abc.Buffer

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

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

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

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

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

Некоторые абстрактные базовые классы также полезны в качестве примесей, упрощающих разработку классов с поддержкой API контейнеров. Например, чтобы написать класс с полной поддержкой API Set, достаточно предоставить три базовых абстрактных метода: __contains__(), __iter__() и __len__(). Абстрактный базовый класс предоставляет остальные методы, например __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). Это предположение вынесено во внутренний метод класса classmethod с именем _from_iterable(), который вызывает cls(iterable) для создания нового множества. Если примесь Set используется в классе с другой сигнатурой конструктора, необходимо переопределить _from_iterable() методом класса или обычным методом, способным создавать новые экземпляры из аргумента-итерируемого объекта.
  2. Чтобы переопределить операции сравнения (предположительно, ради повышения скорости, поскольку их семантика фиксирована), переопределите __le__() и __ge__(); остальные операции будут автоматически работать соответствующим образом.
  3. Примесь Set предоставляет метод _hash() для вычисления хеш-значения множества; однако __hash__() не определён, поскольку не все множества являются хешируемыми или неизменяемыми. Чтобы добавить возможность хеширования множеств с помощью примесей, наследуйтесь одновременно от Set и Hashable, а затем определите __hash__ = Set._hash.

См. также

  • Рецепт OrderedSet — пример реализации на основе MutableSet.
  • Подробнее об абстрактных базовых классах см. в модуле abc и в документе PEP 3119.

© 2001 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/library/collections.abc.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API