collections.abc – Абстрактные базовые классы для контейнеров
Добавлено в версии 3.3: Ранее этот модуль был частью модуля collections.
Исходный код: Lib/_collections_abc.py
Этот модуль предоставляет абстрактные базовые классы, которые можно использовать для проверки, предоставляет ли класс определённый интерфейс; например, является ли он хешируемым или является ли он отображением.
Проверка issubclass() или isinstance() для интерфейса работает одним из трёх способов.
Недавно написанный класс может наследовать напрямую от одного из абстрактных базовых классов. Класс должен предоставлять требуемые абстрактные методы. Остальные методы-примеси наследуются и могут быть переопределены при желании. Другие методы могут быть добавлены по мере необходимости:
pythonclass 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Существующие классы и встроенные классы могут быть зарегистрированы как «виртуальные подклассы» ABC. Эти классы должны определять полный API, включая все абстрактные методы и все методы-примеси. Это позволяет пользователям полагаться на проверки
issubclass()илиisinstance(), чтобы определить, поддерживается ли полный интерфейс. Исключением из этого правила являются методы, которые автоматически выводятся из остальной части API:pythonclass 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__.Некоторые простые интерфейсы напрямую распознаются по наличию требуемых методов (если только эти методы не были установлены в
None):pythonclass 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 |
Наследует от |
Абстрактные методы |
Методы-примеси |
|---|---|---|---|
|
|||
|
|||
|
|||
|
|
||
|
|||
|
|
||
|
|||
|
|||
|
|||
|
|
||
|
Унаследованные методы |
||
|
Унаследованные методы |
||
|
|
||
|
Унаследованные методы |
||
|
|
||
|
Унаследованные методы |
||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|
||
|
|||
|
|
||
|
|
||
|
Сноски
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)¶
Возвращает первый индекс значения.
Возбуждает
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 позволяют проверить, предоставляют ли классы или экземпляры определённую функциональность, например:
size = None
if isinstance(myvar, collections.abc.Sized):
size = len(myvar)
Некоторые ABC также полезны в качестве примесей, упрощающих разработку
классов, поддерживающих контейнерные API. Например, чтобы написать класс, поддерживающий
полный API Set, достаточно предоставить три основных
абстрактных метода: __contains__(), __iter__() и
__len__(). ABC предоставляет остальные методы, такие как
__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 # Метод __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и PEP 3119.