Сообщить об ошибке.

Эмуляция контейнерных типов в классах Python

Следующие методы могут быть определены для реализации контейнерных объектов. Контейнеры обычно представляют собой последовательности (например, списки или кортежи) или сопоставления (например, словари), но могут также представлять другие контейнеры.

Первый набор методов используется либо для имитации последовательности, либо для имитации отображения. Разница в том, что для последовательности допустимыми ключами должны быть целые числа k, для которых 0 <= k < N, где N - длина последовательности, или объекта среза, которые определяют диапазон элементов.

Также рекомендуется, чтобы сопоставления обеспечивали поведение методов keys(), values​​(), items(), get(), clear(), setdefault(), pop(), popitem(), copy() и update() аналогично стандартным объектам словаря Python. Модуль collections.abc предоставляет абстрактный базовый класс MutableMapping, чтобы помочь создать эти методы из базового набора __getitem__(), __setitem__(), __delitem__() и keys().

Изменяемые последовательности должны предоставлять методы append(), count(), index(), extend(), insert(), pop(), remove(), reverse() и sort(), как стандартные объекты списка Python. Наконец, типы последовательностей должны реализовывать сложение (то есть конкатенацию) и умножение (то есть повторение), определяя методы __add__(), __radd__(), __iadd__(), __mul__(), __rmul__() и __imul__(). Они не должны определять другие числовые операторы.

Рекомендуется, чтобы и сопоставления, и последовательности реализовывали метод __contains__(), чтобы обеспечить эффективное использование оператора in. Для сопоставлений, оператор in должен искать ключи сопоставления, для последовательностей он должен искать значения.

Кроме того, рекомендуется, чтобы и сопоставления, и последовательности реализовывали метод __iter__(), чтобы обеспечить эффективную итерацию через контейнер. Для сопоставлений __iter__() должен перебирать ключи объекта, а для последовательностей он должен перебирать значения.

Содержание:


object.__len__(self):

Метод object.__len__() вызывается для реализации встроенной функции len(). Должен возвращать длину объекта, целое число >=0. Кроме того, объект, который не определяет метод __bool__() и чей метод __len__() возвращает ноль, считается ложным в логическом контексте.

Детали реализации CPython: в CPython длина должна быть не больше sys.maxsize. Если длина больше sys.maxsize, то некоторые функции (например, len()) могут вызвать ошибку OverflowError. Чтобы предотвратить возникновение ошибки OverflowError при проверке истинности, объект должен определять метод __bool__().

object.__length_hint__(self):

Метод object.__length_hint__() вызывается для реализации operator.length_hint(). Должен возвращать оценочную длину объекта (которая может быть больше или меньше фактической длины). Длина должна быть целым числом >= 0. Возвращаемое значение также может быть NotImplemented, что обрабатывается так же, как если бы метод __length_hint__ вообще не существовал. Этот метод является чисто оптимизационным и никогда не требуется для корректности.

Примечание. Срезы выполняется исключительно следующими тремя способами. Вызовом вроде:

a[1:2] = b

# что транслируется как

a[slice(1, 2, None)] = b

И так далее. Отсутствующие элементы среза всегда заполняются значением None.

object.__getitem__(self, key):

Метод object.__getitem__() вызывается для реализации возврата значения self[key]. Для типов последовательности принимаемые ключи key должны быть целыми числами и объектами среза.

Обратите внимание, что специальная интерпретация отрицательных индексов (если класс имитирует тип последовательности) зависит от метода __getitem__().

  • Если ключ key имеет неподходящий тип, то может возникнуть ошибка TypeError.
  • Если значение выходит за пределы набора индексов для последовательности (после любой специальной интерпретации отрицательных значений), то следует вызвать исключение IndexError.
  • Для типов сопоставления, если ключ key отсутствует (не в контейнере), то необходимо вызвать исключение KeyError.

Обратите внимание, что для циклов ожидается, что для недопустимых индексов будет вызвана ошибка IndexError, чтобы обеспечить правильное определение конца последовательности.

object.__setitem__(self, key, value):

Метод object.__setitem__() вызывается для реализации присвоения self[key]. То же описание, что и для специального метода __getitem__().

Метод должен быть реализован только для сопоставлений (словарей), если объекты поддерживают изменения значений для ключей key, или если могут быть добавлены новые ключи, или для последовательностей, если элементы могут быть заменены.

Для неправильных значений ключей должны возникать те же исключения, что и для метода __getitem__().

object.__delitem__(self, key):

Метод object.__delitem__() вызывается для реализации удаления self[key]. То же описание, что и для специального метода __getitem__().

Метод должен быть реализован только для сопоставлений (словарей), если объекты поддерживают удаление ключей key, или для последовательностей, если элементы могут быть удалены из последовательности.

Для неправильных значений ключей должны возникать те же исключения, что и для метода __getitem__().

object.__missing__(self, key):

Метод object.__missing__() вызывается dict.__getitem__() для реализации self[key] для подклассов dict, когда ключ отсутствует в словаре.

object.__iter__(self):

Метод object.__iter__() вызывается, когда для контейнера требуется итератор. Этот метод должен возвращать новый объект-итератор, который может перебирать все объекты в контейнере. Для сопоставлений он должен перебирать ключи контейнера.

Объекты-итераторы также должны реализовать этот метод. Дополнительные сведения об объектах-итераторах смотрите в разделе "Типы итераторов".

object.__reversed__(self):

Метод object.__reversed__() вызывается (если есть) встроенной функцией reversed() для реализации обратной итерации. Он должен вернуть новый объект-итератор, который выполняет итерацию по всем объектам в контейнере в обратном порядке.

Если метод __reversed__() не указан, то встроенная функция reversed() вернется к использованию протокола последовательности (__len__() и __getitem__()). Объекты, поддерживающие протокол последовательности, должны предоставлять __reversed__() только в том случае, если они могут предоставить реализацию, более эффективную, чем та, которую предоставляет reversed().

Операторы проверки членства in и not in обычно реализуются как итерация через контейнер. Однако объекты-контейнеры могут предоставлять следующий специальный метод с более эффективной реализацией, который также не требует, чтобы объект был итерируемым.

object.__contains__(self, item):

Метод object.__contains__() вызывается для реализации операторов проверки вхождения/членства.

Метод должен возвращать True, если элемент находится в self, иначе False. В отображениях объектов, следует учитывать ключи отображения, а не значения или пары (key, value).

Для объектов, которые не определяют __contains__(), тест членства сначала пытается выполнить итерацию через метод __iter__(), затем старый протокол итерации последовательности через __getitem__().