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 | Наследуется от | Абстрактные методы | Методы миксина |
|---|---|---|---|
| |||
| |||
| |||
|
| ||
| |||
|
| ||
| |||
| |||
| |||
|
| ||
| Наследованные | ||
| Наследованные | ||
|
| ||
| Наследованные | ||
|
| ||
| Наследованные | ||
| |||
| |||
| |||
| |||
| |||
|
| ||
|
|
| ||
|
|
Сноски
-
1(1,2,3,4,5,6,7,8,9,10,11,12,13,14) -
Эти ABC переопределяют
__subclasshook__()для поддержки тестирования интерфейса путём проверки наличия необходимых методов и отсутствия присвоения им значенияNone. Это работает только для простых интерфейсов. Более сложные интерфейсы требуют регистрации или прямого наследования. -
2 -
Проверка
isinstance(obj, Iterable)обнаруживает классы, зарегистрированные какIterable, или имеющие метод__iter__(), но не обнаруживает классы, которые итерируются с помощью метода__getitem__(). Единственный надёжный способ определить, является ли объект итерируемым, заключается в вызовеiter(obj).
Классы абстрактного базиса коллекций — подробные описания
-
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 для классов контейнеров с размером и итераторами.
New in version 3.6.
-
class collections.abc.Iterator -
ABC для классов, предоставляющих методы
__iter__()и__next__(). См. также определение итератора.
-
class collections.abc.Reversible -
ABC для итерируемых классов, также предоставляющих метод
__reversed__().New in version 3.6.
-
class collections.abc.Generator -
ABC для классов генераторов, которые реализуют протокол, определённый в PEP 342, расширяющий итераторы с методами
send(),throw()иclose().New in version 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 для ожидаемых объектов, которые могут быть использованы в выражениях
await. Пользовательские реализации должны предоставить метод__await__().Объекты корутины и экземпляры ABC
Coroutineявляются экземплярами этого ABC.Примечание
В CPython генераторные корутины (генераторы, декорированные с
@types.coroutine) являются ожидаемыми, даже если у них нет метода__await__(). Использованиеisinstance(gencoro, Awaitable)для них вернётFalse. Используйтеinspect.isawaitable()для их обнаружения.New in version 3.5.
-
class collections.abc.Coroutine -
ABC для совместимых с корутинами классов. Они реализуют следующие методы, определённые в Объекты корутины:
send(),throw()иclose(). Пользовательские реализации также должны реализовывать__await__(). Все экземплярыCoroutineтакже являются экземплярамиAwaitable.Примечание
В CPython генераторные корутины (генераторы, декорированные с
@types.coroutine) являются ожидаемыми, даже если у них нет метода__await__(). Использованиеisinstance(gencoro, Coroutine)для них вернётFalse. Используйтеinspect.isawaitable()для их обнаружения.New in version 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.
Новая в версии 3.6.
Примеры и рецепты
ABC позволяют нам узнать, предоставляют ли классы или экземпляры определённый функционал, например:
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). Это предположение вынесено во внутреннийclassmethodс именем_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.11/library/collections.abc.html