collections.abc — Абстрактные базовые классы для контейнеров
Добавлено в версии 3.3: Ранее этот модуль был частью модуля collections.
Исходный код: Lib/_collections_abc.py
Этот модуль предоставляет абстрактные базовые классы, которые можно использовать, чтобы проверить, предоставляет ли класс определённый интерфейс; например, является ли он хешируемым или является ли он отображением.
Проверка интерфейса с помощью issubclass() или isinstance() работает одним из трёх способов.
-
Новый класс может напрямую наследоваться от одного из абстрактных базовых классов. Класс должен предоставить требуемые абстрактные методы. Остальные методы-миксины наследуются и при необходимости могут быть переопределены. При необходимости можно добавить другие методы:
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
-
Существующие классы и встроенные классы можно зарегистрировать как «виртуальные подклассы» 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__в качестве запасного варианта. -
Некоторые простые интерфейсы можно распознать непосредственно по наличию требуемых методов (если только для этих методов не задано значение
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 | Наследуется от | Абстрактные методы | Методы-миксины |
|---|---|---|---|
| |||
| |||
| |||
|
| ||
| |||
|
| ||
| |||
| |||
| |||
|
| ||
| Унаследованные методы | ||
| Унаследованные методы | ||
|
| ||
| Унаследованные методы | ||
|
| ||
| Унаследованные методы | ||
| |||
| |||
| |||
| |||
| |||
|
| ||
| |||
|
| ||
|
| ||
|
Примечания
Абстрактные базовые классы коллекций — подробные описания
-
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 в качестве примеси:
- Поскольку некоторые операции над множествами создают новые множества, методам-примесям по умолчанию нужен способ создавать новые экземпляры из итерируемого объекта. Предполагается, что конструктор класса имеет сигнатуру вида
ClassName(iterable). Это предположение вынесено во внутренний метод классаclassmethodс именем_from_iterable(), который вызываетcls(iterable)для создания нового множества. Если примесьSetиспользуется в классе с другой сигнатурой конструктора, необходимо переопределить_from_iterable()методом класса или обычным методом, способным создавать новые экземпляры из аргумента-итерируемого объекта. - Чтобы переопределить операции сравнения (предположительно, ради повышения скорости, поскольку их семантика фиксирована), переопределите
__le__()и__ge__(); остальные операции будут автоматически работать соответствующим образом. - Примесь
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