← Назад к вопросам
Какие методы должна реализовывать последовательность в Python?
2.0 Middle🔥 41 комментариев
#Git и VCS
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Методы последовательности в Python
В Python последовательность — это упорядоченный набор элементов с доступом по индексу. Существует протокол (ABC — Abstract Base Class), определяющий, какие методы должны реализовать пользовательские последовательности.
Обязательные методы (Minimal Protocol)
Для создания базовой последовательности необходимо реализовать как минимум два метода:
from collections.abc import Sequence
class MySequence(Sequence):
def __init__(self, data):
self._data = data
def __getitem__(self, index):
"""Получение элемента по индексу (обязательно)"""
if isinstance(index, slice):
return MySequence(self._data[index])
return self._data[index]
def __len__(self):
"""Получение длины последовательности (обязательно)"""
return len(self._data)
# Использование
seq = MySequence([1, 2, 3, 4, 5])
print(seq[2]) # 3
print(len(seq)) # 5
print(seq[1:3]) # MySequence([2, 3])
Эти два метода достаточно для получения остального функционала автоматически!
Автоматически полученные методы
Когда вы наследуетесь от Sequence, получаете эти методы бесплатно:
seq = MySequence([1, 2, 3, 1, 4])
# Проверка содержимого
print(2 in seq) # True (через __getitem__)
print(seq.index(1)) # 0 (первый индекс элемента)
print(seq.count(1)) # 2 (количество элементов)
# Итерация
for item in seq: # Работает через __getitem__
print(item)
# Реверс
print(list(reversed(seq))) # [4, 1, 3, 2, 1]
# Распаковка
a, b, c, *rest = seq # Работает через __iter__
Основные методы, наследуемые от Sequence
seq = MySequence([1, 2, 3, 4, 5])
# 1. __contains__ (in оператор)
print(3 in seq) # True
print(10 in seq) # False
# 2. __iter__ (итерация)
iterator = iter(seq)
print(next(iterator)) # 1
print(next(iterator)) # 2
# 3. __reversed__ (обратный порядок)
for item in reversed(seq):
print(item) # 5, 4, 3, 2, 1
# 4. index(value, start=0, stop=None) - индекс элемента
print(seq.index(3)) # 2
# 5. count(value) - количество вхождений
seq2 = MySequence([1, 2, 1, 3, 1])
print(seq2.count(1)) # 3
Полная иерархия методов
from collections.abc import Sequence, MutableSequence
# Читаемая последовательность (неизменяемая)
class ImmutableSeq(Sequence):
def __init__(self, data):
self._data = tuple(data)
def __getitem__(self, index):
return self._data[index]
def __len__(self):
return len(self._data)
# Изменяемая последовательность
class MutableSeq(MutableSequence):
def __init__(self, data):
self._data = list(data)
def __getitem__(self, index):
return self._data[index]
def __setitem__(self, index, value):
"""Установка значения (обязательно для MutableSequence)"""
self._data[index] = value
def __delitem__(self, index):
"""Удаление элемента (обязательно для MutableSequence)"""
del self._data[index]
def __len__(self):
return len(self._data)
def insert(self, index, value):
"""Вставка элемента (обязательно для MutableSequence)"""
self._data.insert(index, value)
# Использование
seq = MutableSeq([1, 2, 3])
seq[1] = 20 # Изменение
seq.insert(2, 100) # Вставка
seq.append(4) # Автоматический append!
print(seq._data) # [1, 20, 100, 3, 4]
Методы, автоматичные для MutableSequence
При реализации трёх методов (__setitem__, __delitem__, insert) вы получаете:
seq = MutableSeq([1, 2, 3, 4, 5])
# Наследуемые методы:
seq.append(6) # Добавить в конец
seq.extend([7, 8]) # Расширить
seq.insert(0, 0) # Вставить
seq.remove(3) # Удалить первое вхождение
seq.pop() # Удалить последний
seq.pop(0) # Удалить по индексу
seq.clear() # Очистить
seq.reverse() # Развернуть на месте
seq += [10, 11] # +=
seq *= 2 # *=
Сравнение с встроенными типами
# list - MutableSequence
print(isinstance([1, 2, 3], MutableSequence)) # True
# tuple - Sequence
print(isinstance((1, 2, 3), Sequence)) # True
print(isinstance((1, 2, 3), MutableSequence)) # False
# str - Sequence
print(isinstance("hello", Sequence)) # True
Лучшие практики
# ✅ Хорошо - используй ABC для типизации
def process_sequence(seq: Sequence) -> None:
for item in seq:
print(item)
# ✅ Правильное наследование
class CustomList(MutableSequence):
def __init__(self, data=None):
self._data = list(data or [])
def __getitem__(self, index):
if isinstance(index, slice):
return CustomList(self._data[index])
return self._data[index]
def __setitem__(self, index, value):
self._data[index] = value
def __delitem__(self, index):
del self._data[index]
def __len__(self):
return len(self._data)
def insert(self, index, value):
self._data.insert(index, value)
# ❌ Плохо - полное переопределение методов
class BadList:
def __getitem__(self, index):
# ...
def __setitem__(self, index, value):
# ...
# Пришлось бы переопределить все методы вручную!
Использование правильных ABC экономит время и обеспечивает совместимость с остальным кодом Python.