Программа курса:
Магические методы __getitem__, __setitem__ и __delitem__

В Python магические методы позволяют вам определять специальное поведение для экземпляров вашего класса. Одними из наиболее полезных являются методы, которые отвечают за доступ, изменение и удаление элементов по индексу или ключу: __getitem__, __setitem__ и __delitem__. Эти методы дают возможность экземплярам вашего класса вести себя подобно спискам, словарям и другим стандартным коллекциям Python.
Метод __getitem__
Метод __getitem__ отвечает за доступ к элементам экземпляра класса по индексу или ключу. По умолчанию, если у объекта нет этого метода, попытка обращения по индексу приводит к ошибке TypeError: 'Object' object is not subscriptable. Это значит, что объект не поддерживает операцию индексирования, как это делают списки и словари.
Допустим, мы создаем класс Matrix, который содержит двумерный массив значений. Мы хотим обращаться к элементам матрицы по индексу, например, matrix[1][2], но без __getitem__ это невозможно:
class Matrix:
def __init__(self, values):
self.values = values
matrix = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrix[1][2]) # Ошибка TypeError
Для того чтобы этот код работал, нужно определить метод __getitem__:
class Matrix:
def __init__(self, values):
self.values = values
def __getitem__(self, index):
if isinstance(index, int) and 0 <= index < len(self.values):
return self.values[index]
else:
raise IndexError("Индекс вне границ матрицы")
matrix = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrix[1][2]) # Вывод: 6
В данном примере __getitem__ проверяет, что индекс в пределах допустимого диапазона, а затем возвращает нужную строку матрицы. Если передать недопустимый индекс, то возбуждается исключение IndexError.
Теперь добавим поддержку обращения к элементам матрицы по строковому ключу: если передается строка, мы будем использовать ее длину как индекс:
class Matrix:
def __init__(self, values):
self.values = values
def __getitem__(self, index):
if isinstance(index, int):
if 0 <= index < len(self.values):
return self.values[index]
else:
raise IndexError("Индекс вне границ матрицы")
elif isinstance(index, str):
index = len(index)
if 0 <= index < len(self.values):
return self.values[index]
else:
raise IndexError("Индекс вне границ матрицы")
else:
raise TypeError("Недопустимый тип индекса")
matrix = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrix["ab"]) # Вывод: [7, 8, 9]
Метод __setitem__
Метод __setitem__ позволяет изменять значения в объекте по индексу или ключу. Он вызывается при присваивании значения с помощью синтаксиса obj[index] = value. Рассмотрим, как можно изменить значения элементов в матрице:
class Matrix:
def __init__(self, values):
self.values = values
def __getitem__(self, index):
return self.values[index]
def __setitem__(self, index, value):
if isinstance(index, int) and 0 <= index < len(self.values):
self.values[index] = value
elif isinstance(index, str):
index = len(index)
if 0 <= index < len(self.values):
self.values[index] = value
else:
raise IndexError("Индекс вне границ матрицы")
else:
raise TypeError("Недопустимый тип индекса")
matrix = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
matrix[1] = [10, 11, 12]
matrix["tw"] = [13, 14, 15]
print(matrix.values) # Вывод: [[1, 2, 3], [10, 11, 12], [13, 14, 15]]
Метод __delitem__
Метод __delitem__ позволяет удалять элементы по индексу или ключу. Он вызывается при использовании оператора del obj[index]. По умолчанию, метод удаляет элемент по указанному индексу. Однако мы можем модифицировать его так, чтобы удалялись все элементы, равные переданному значению:
class Matrix:
def __init__(self, values):
self.values = values
def __getitem__(self, index):
return self.values[index]
def __setitem__(self, index, value):
self.values[index] = value
def __delitem__(self, key):
if isinstance(key, int):
del self.values[key]
elif isinstance(key, list):
for value in key:
while value in self.values:
self.values.remove(value)
else:
raise TypeError("Неверный тип ключа")
matrix = Matrix([3, 4, 4, 5, 6, 4])
del matrix[4] # Удаляет элемент с индексом 4
print(matrix.values) # Вывод: [3, 4, 4, 5, 4]
del matrix[[4, 5]] # Удаляет все четверки и пятерки
print(matrix.values) # Вывод: [3]
В этом примере __delitem__ может принимать список значений и удаляет все вхождения элементов, указанных в этом списке. Это позволяет выполнять более сложные операции удаления.
Вот таблица по лекции о методах __getitem__, __setitem__, и __delitem__:
| Тема | Описание |
|---|---|
Метод __getitem__ | Отвечает за доступ к элементам объекта по индексу или ключу. Если метод не реализован, объект не поддерживает индексирование (TypeError). |
| Пример использования | В классе Matrix метод __getitem__ позволяет обращаться к элементам матрицы по индексу, как в списке: matrix[1][2]. |
| Поддержка строковых ключей | Метод может обрабатывать строковые индексы, где длина строки используется в качестве индекса: matrix["abc"] (длина строки "abc" равна 3). |
Метод __setitem__ | Позволяет изменять значения элементов по индексу или ключу с помощью синтаксиса obj[index] = value. |
| Пример изменения значений | В классе Matrix можно менять значения как по целочисленным, так и по строковым индексам: matrix[1] = [10, 11, 12], matrix["four"] = [13, 14, 15]. |
Метод __delitem__ | Удаляет элементы по индексу или ключу. Вызывается при использовании оператора del obj[index]. |
| Пример удаления элементов | В классе Matrix метод может удалять элементы по индексу (del matrix[4]) или по списку значений (del matrix[[4, 5]], удаляются все четверки и пятерки). |
| Итог | Методы __getitem__, __setitem__, и __delitem__ позволяют кастомным классам работать с элементами как стандартные коллекции, упрощая доступ, изменение и удаление. |
Таблица охватывает основные моменты лекции и примеры использования этих магических методов в Python.
Итог:
Магические методы __getitem__, __setitem__ и __delitem__ дают гибкость для работы с кастомными классами, позволяя им вести себя как стандартные коллекции. Это упрощает доступ к элементам, их изменение и удаление, а также предоставляет возможности для сложных логических операций.
Попробуйте самостоятельно реализовать аналогичные методы для других структур данных, чтобы лучше понять их применение!
xsnm
,Traceback (most recent call last):
File "F:\pythom\basics of classes.py", line 21, in <module>
print(matrix["abc"]) # Вывод: [4, 5, 6] (длина строки "abc" равна 3) ??????? [ 0,1,2]=>[''ab']
~~~~~~^^^^^^^
File "F:\pythom\basics of classes.py", line 16, in __getitem__
raise IndexError("Индекс вне границ матрицы")
IndexError: Индекс вне границ матрицы
admin
,xsnm, Я поправил все выкрутасы с индексами в примерах, остальные треды закрою так-как они все на эту же тему.