collections.abc
— Абстрактные базовые классы для контейнеров¶
Добавлено в версии 3.3: Раньше этот модуль был частью модуля collections
.
Исходный код: Lib/_collections_abc.py.
Этот модуль предоставляет abstract base classes, который можно использовать для проверки того, предоставляет ли класс определенный интерфейс; например, является ли он хэшируемым или является ли он отображением.
Тест issubclass()
или isinstance()
для интерфейса работает одним из трех способов.
1) A newly written class can inherit directly from one of the abstract base classes. The class must supply the required abstract methods. The remaining mixin methods come from inheritance and can be overridden if desired. Other methods may be added as needed:
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) Existing classes and built-in classes can be registered as «virtual
subclasses» of the ABCs. Those classes should define the full API
including all of the abstract methods and all of the mixin methods.
This lets users rely on issubclass()
or isinstance()
tests
to determine whether the full interface is supported. The exception to
this rule is for methods that are automatically inferred from the rest
of the 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-operator, логика iteration и функция reversed()
автоматически переходят к использованию __getitem__
и __len__
.
3) Some simple interfaces are directly recognizable by the presence of
the required methods (unless those methods have been set to
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.
Коллекции Абстрактные базовые классы¶
Модуль коллекций предлагает следующее ABCs:
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__()
. Единственным надежным способом определить, является ли объект iterable, является вызов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__()
. Единственным надежным способом определить, является ли объект iterable, является вызовiter(obj)
.
-
class
collections.abc.
Collection
¶ ABC для размерных классов итерируемых контейнеров.
Добавлено в версии 3.6.
-
class
collections.abc.
Iterator
¶ ABC для классов, предоставляющих методы
__iter__()
и__next__()
. См. также определение iterator.
-
class
collections.abc.
Reversible
¶ ABC для классов iterable, которые также предоставляют метод
__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
¶ Азбуки для доступных только для чтения и изменяемых sequences.
Примечание по реализации: Некоторые из методов миксинов, такие как
__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
¶ Азбуки для доступных только для чтения и изменяемых mappings.
-
class
collections.abc.
MappingView
¶ -
class
collections.abc.
ItemsView
¶ -
class
collections.abc.
KeysView
¶ -
class
collections.abc.
ValuesView
¶ Азбука для отображения, элементов, ключей и значений views.
-
class
collections.abc.
Awaitable
¶ ABC для объектов awaitable, которые могут быть использованы в выражениях
await
. Пользовательские реализации должны предоставлять метод__await__()
.Coroutine объекты и экземпляры
Coroutine
ABC все являются экземплярами этого ABC.Примечание
В CPython coroutines на основе генераторов (генераторы, украшенные
types.coroutine()
илиasyncio.coroutine()
) являются awaitables, даже если у них нет метода__await__()
. Использованиеisinstance(gencoro, Awaitable)
для них вернетFalse
. Для их обнаружения используйтеinspect.isawaitable()
.Добавлено в версии 3.5.
-
class
collections.abc.
Coroutine
¶ ABC для классов, совместимых с корутинами. Они реализуют следующие методы, определенные в Объекты Coroutine:
send()
,throw()
иclose()
. Пользовательские реализации должны также реализовывать__await__()
. Все экземплярыCoroutine
также являются экземплярамиAwaitable
. См. также определение coroutine.Примечание
В CPython coroutines на основе генераторов (генераторы, украшенные
types.coroutine()
илиasyncio.coroutine()
) являются awaitables, даже если у них нет метода__await__()
. Использованиеisinstance(gencoro, Coroutine)
для них вернетFalse
. Для их обнаружения используйтеinspect.isawaitable()
.Добавлено в версии 3.5.
-
class
collections.abc.
AsyncIterable
¶ ABC для классов, предоставляющих метод
__aiter__
. См. также определение asynchronous iterable.Добавлено в версии 3.5.
-
class
collections.abc.
AsyncIterator
¶ ABC для классов, предоставляющих методы
__aiter__
и__anext__
. См. также определение asynchronous iterator.Добавлено в версии 3.5.
Примеры и рецепты¶
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 # The __and__() method is supported automatically
Примечания по использованию Set
и MutableSet
в качестве миксина:
Поскольку некоторые операции с множествами создают новые множества, методы миксина по умолчанию нуждаются в способе создания новых экземпляров из итерабельной таблицы. Предполагается, что конструктор класса имеет сигнатуру в виде
ClassName(iterable)
. Это предположение выводится во внутренний метод класса_from_iterable()
, который вызываетcls(iterable)
для создания нового множества. Если миксинSet
используется в классе с другой сигнатурой конструктора, вам необходимо переопределить_from_iterable()
с помощью classmethod или обычного метода, который может создавать новые экземпляры из аргумента iterable.Чтобы отменить сравнения (предположительно для скорости, так как семантика фиксирована), переопределите
__le__()
и__ge__()
, тогда остальные операции автоматически последуют за ними.Миксин
Set
предоставляет метод_hash()
для вычисления хэш-значения для набора; однако__hash__()
не определен, поскольку не все наборы являются хэшируемыми или неизменяемыми. Чтобы добавить хэшируемость множества с помощью миксинов, наследуйте отSet()
иHashable()
, а затем определите__hash__ = Set._hash
.
См.также
OrderedSet recipe для примера, построенного на
MutableSet
.