Содержание страницы
collections.abc – Абстрактные базовые классы для контейнеров¶collections.abc – Abstract Base Classes for Containers
Добавлено в версии 3.3: Ранее этот модуль был частью модуля collections.
Исходный код: Lib/_collections_abc.py
Этот модуль предоставляет абстрактные базовые классы, которые можно использовать для проверки, предоставляет ли класс определённый интерфейс; например, является ли он хешируемым или отображением.
Проверка issubclass() или isinstance() для интерфейса работает одним
из трёх способов.
Новый класс может наследовать напрямую от одного из абстрактных базовых классов. Класс должен предоставлять требуемые абстрактные методы. Остальные методы-примеси наследуются и могут быть переопределены при необходимости. Другие методы могут быть добавлены по мере необходимости:
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
Существующие и встроенные классы могут быть зарегистрированы как «виртуальные подклассы» 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__.Некоторые простые интерфейсы напрямую распознаются по наличию требуемых методов (если только эти методы не были установлены в
None):class E: def __iter__(self): ... def __next__(self): ...
>>> 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 |
Наследует от |
Абстрактные методы |
Методы-примеси |
|---|---|---|---|
|
|||
|
|||
|
|||
|
|
||
|
|||
|
|
||
|
|||
|
|||
|
|||
|
|
||
|
Унаследованные методы |
||
|
Унаследованные методы |
||
|
|
||
|
Унаследованные методы |
||
|
|
||
|
Унаследованные методы |
||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|
||
|
|||
|
|
||
|
|
||
|
Сноски
Абстрактные базовые классы коллекций – Подробные описания¶Collections Abstract Base Classes – Detailed Descriptions
- class collections.abc.Container¶
ABC для классов, которые предоставляют метод
__contains__().
- class collections.abc.Hashable¶
ABC для классов, которые предоставляют метод
__hash__().
- 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)¶
Возвращает индекс первого вхождения value.
Возбуждает
ValueError, если значение отсутствует.Поддержка аргументов start и stop является необязательной, но рекомендуется.
Изменено в версии 3.5: Метод
index()получил поддержку аргументов stop и start.
Устарело с версии 3.12, будет удалено в версии 3.17: ABC
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¶
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) являются ожидаемыми объектами, даже если они не имеют метода__await__(). Использованиеisinstance(gencoro, Awaitable)для них вернётFalse. Для их обнаружения используетсяinspect.isawaitable().Добавлено в версии 3.5.
- class collections.abc.Coroutine¶
ABC для классов, совместимых с корутинами. Они реализуют следующие методы, определённые в Объекты корутины:
send(),throw()иclose(). Пользовательские реализации также должны реализовать__await__(). Все экземплярыCoroutineтакже являются экземплярамиAwaitable.Примечание
В CPython корутины на основе генераторов (генераторы, декорированные с помощью
@types.coroutine) являются ожидаемыми объектами, даже если они не имеют метода__await__(). Использованиеisinstance(gencoro, Coroutine)для них вернётFalse. Для их обнаружения используетсяinspect.isawaitable().См. Аннотирование генераторов и корутин для подробностей об использовании
Coroutineв аннотациях типов. Вариантность и порядок параметров типа соответствуют таковым уGenerator.Добавлено в версии 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.
См. Аннотирование генераторов и корутин для подробностей об использовании
AsyncGeneratorв аннотациях типов.Добавлено в версии 3.6.
- class collections.abc.Buffer¶
ABC для классов, предоставляющих метод
__buffer__(), реализующих протокол буфера. См. PEP 688.Добавлено в версии 3.12.
Примеры и рецепты¶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 в качестве примеси:
Поскольку некоторые операции над множествами создают новые множества, методы по умолчанию в миксинах должны уметь создавать новые экземпляры из итерируемого объекта. Предполагается, что конструктор класса имеет сигнатуру вида
ClassName(iterable). Это предположение вынесено во внутреннийclassmethod, называемый_from_iterable(), который вызываетcls(iterable)для создания нового множества. Если миксинSetиспользуется в классе с другой сигнатурой конструктора, потребуется переопределить_from_iterable()с помощью метода класса или обычного метода, который может создавать новые экземпляры из итерируемого аргумента.Чтобы переопределить сравнения (предположительно для скорости, так как семантика фиксирована), переопределите
__le__()и__ge__(); тогда остальные операции автоматически последуют их примеру.Миксин
Setпредоставляет метод_hash()для вычисления хеш-значения множества; однако__hash__()не определён, поскольку не все множества являются хешируемыми или неизменяемыми. Чтобы добавить хешируемость множеству с помощью миксинов, наследуйтесь от обоихSetиHashable, а затем определите__hash__ = Set._hash.
См. также
Рецепт OrderedSet для примера, построенного на
MutableSet.Для получения дополнительной информации об ABC см. модуль
abcи .
Эта страница – перевод. Оригинал на английском – docs.python.org. Нашли неточность? Сообщите нам.