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__(next): ...
>>> issubclass(E, Iterable) True >>> isinstance(E(), Iterable) True
Сложные интерфейсы не поддерживают этот последний метод, потому что интерфейс представляет собой больше, чем просто наличие имён методов. Интерфейсы определяют семантику и взаимосвязи между методами, которые нельзя вывести только из наличия определённых имён методов. Например, знание того, что класс предоставляет __getitem__, __len__, и __iter__ недостаточно для различения Sequence от Mapping.
Новое в версии 3.9: Эти абстрактные классы теперь поддерживают []. См. Тип обобщённого псевдонима и PEP 585.
Абстрактные базовые классы коллекций
Модуль collections предоставляет следующие ABC:
ABC | Наследуется от | Абстрактные методы | Методы-микшины |
|---|---|---|---|
| |||
| |||
| |||
|
| ||
| |||
|
| ||
| |||
| |||
| |||
|
| ||
| Наследуемые методы | ||
| Наследуемые методы | ||
|
| ||
| Наследуемые методы | ||
|
| ||
| Наследуемые методы | ||
| |||
| |||
| |||
| |||
| |||
|
| ||
|
|
| ||
|
|
Примечания
-
1(1,2,3,4,5,6,7,8,9,10,11,12,13,14) -
Эти ABC переопределяют
object.__subclasshook__()для поддержки тестирования интерфейса путем проверки наличия необходимых методов и того, что они не установлены в значениеNone. Это работает только для простых интерфейсов. Более сложные интерфейсы требуют регистрации или прямого наследования. -
2 -
Проверка
isinstance(obj, Iterable)обнаруживает классы, зарегистрированные какIterableили имеющие метод__iter__(), но не обнаруживает классы, которые итерируются с помощью метода__getitem__(). Единственный надёжный способ определить, является ли объект итерируемым, заключается в вызовеiter(obj).
Классы абстрактного базового уровня Collections – подробные описания
-
class collections.abc.Container -
ABC для классов, предоставляющих метод
__contains__().
-
class collections.abc.Hashable -
ABC для классов, предоставляющих метод
__hash__().
-
class collections.abc.Sized -
ABC для классов, предоставляющих метод
__len__().
-
class collections.abc.Callable -
ABC для классов, предоставляющих метод
__call__().
-
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(). Смотрите также определение генератора.Введено в версии 3.5.
-
class collections.abc.Sequence -
class collections.abc.MutableSequence -
class collections.abc.ByteString -
ABC для неизменяемых и изменяемых последовательностей.
Примечание по реализации: некоторые методы-миксины, такие как
__iter__(),__reversed__()иindex(), делают повторные вызовы к базовому методу__getitem__(). Поэтому, если__getitem__()реализован с постоянной скоростью доступа, методы-миксины будут иметь линейную производительность. Однако, если базовый метод имеет линейную производительность (как в случае с связанным списком), миксины будут иметь квадратичную производительность и, вероятно, потребуют переопределения.Изменено в версии 3.5: Метод index() получил поддержку аргументов stop и start.
-
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 для awaitable объектов, которые могут использоваться в выражениях
await. Пользовательские реализации должны предоставлять метод__await__().Объекты генераторов и экземпляры ABC
Coroutineявляются экземплярами этого ABC.Примечание
В CPython, генераторы-корутины (генераторы, оформленные с помощью
types.coroutine()илиasyncio.coroutine()) являются awaitable, даже если у них нет метода__await__(). Использованиеisinstance(gencoro, Awaitable)для них вернётFalse. Используйтеinspect.isawaitable()для их обнаружения.Введено в версии 3.5.
-
class collections.abc.Coroutine -
ABC для совместимых с корутинами классов. Они реализуют следующие методы, определённые в Объектах корутин:
send(),throw()иclose(). Пользовательские реализации также должны реализовывать__await__(). Все экземплярыCoroutineтакже являются экземплярамиAwaitable. Смотрите также определение корутины.Примечание
В CPython, генераторы-корутины (генераторы, оформленные с помощью
types.coroutine()илиasyncio.coroutine()) являются awaitable, даже если у них нет метода__await__(). Использованиеisinstance(gencoro, Coroutine)для них вернётFalse. Используйтеinspect.isawaitable()для их обнаружения.Введено в версии 3.5.
-
class collections.abc.AsyncIterable -
ABC для классов, предоставляющих метод
__aiter__. Смотрите также определение асинхронного итерируемого объекта.Введено в версии 3.5.
-
class collections.abc.AsyncIterator -
ABC для классов, предоставляющих методы
__aiter__и__anext__. Смотрите также определение асинхронного итератора.Введено в версии 3.5.
Примеры и рецепты
ABCs позволяют нам спрашивать классы или экземпляры, предоставляют ли они определённую функциональность, например:
size = None
if isinstance(myvar, collections.abc.Sized):
size = len(myvar)
Несколько ABC также полезны в качестве миксинов, которые облегчают разработку классов, поддерживающих контейнерные API. Например, для написания класса, поддерживающего полный Set API, достаточно предоставить три основополагающих абстрактных метода: __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 # The __and__() method is supported automatically
Примечания по использованию Set и MutableSet в качестве миксина:
- Поскольку некоторые операции над множествами создают новые множества, стандартные методы миксина должны иметь возможность создавать новые экземпляры из итерируемого объекта. Предполагается, что конструктор класса имеет сигнатуру в виде
ClassName(iterable). Это предположение вынесено в внутренний метод класса_from_iterable(), который вызываетcls(iterable), чтобы создать новое множество. Если миксинSetиспользуется в классе с другой сигнатурой конструктора, вам нужно переопределить_from_iterable()с методом класса или обычным методом, который может создавать новые экземпляры из итерируемого аргумента. - Чтобы переопределить сравнения (вероятно, для повышения скорости, так как семантика фиксирована), переопределите
__le__()и__ge__(), затем другие операции будут автоматически работать аналогичным образом. - Миксин
Setпредоставляет метод_hash()для вычисления значения хэша множества; однако,__hash__()не определен, так как не все множества являются хешируемыми или неизменяемыми. Чтобы добавить хешируемость множеству с помощью миксинов, наследуйтесь отSet()иHashable(), а затем определите__hash__ = Set._hash.
См. также
- Рецепт OrderedSet для примера, построенного на
MutableSet. - Для получения дополнительной информации об ABC см. модуль
abcи PEP 3119.
© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/library/collections.abc.html