Перегрузка операторов. Доступ к элементам по индексу. Методы __getitem__() и __setitem__()
Содержание
- 1. Перегрузка доступа по индексу [ ]. Метод __getitem__()
- 2. Перегрузка доступа по индексу [ ]. Установка нового значения. Метод __setitem__()
- 3. Пример, демонстрирующий реализацию массива комплексных чисел и доступ по индексу к элементам массива
- 4. Пример, демонстрирующий доступ к объекту класса по индексу. Реализация классов Point и ListPoints
- Связанные темы
Поиск на других ресурсах:
1. Перегрузка доступа по индексу [ ]. Метод __getitem__()
Чтобы обеспечить доступ по индексу в классе нужно реализовать методы __getitem__() и __setitem__(). Как правило, доступ по индексу требуется в классах реализующих наборы данных (массивы, списки и т.п.).
Метод __getitem__() вызывается, когда нужно считать данные по индексу. Приблизительный вид объявления метода в классе может быть следующим
class ClassName: # Составляющие класса ... def __getitem__(self, index): ... return self.objName[index]
здесь
- ClassName – имя класса;
- objName – итерированный объект, являющийся списком, кортежем и т.п.;
- index – позиция (индекс) элемента в объекте objName.
Можно, конечно, реализовать метод __getitem__() и не для итерированного объекта, вкладывая в него определенный смысл.
После объявления метода __getitem__() можно обращаться к объекту класса привычным способом с помощью квадратных скобок [ ]
value = ClassName[index] # вызывается метод __getitem__()
здесь
- value – некоторое значение;
- index – позиция (индекс) итерированного объекта в классе ClassName.
⇑
2. Перегрузка доступа по индексу [ ]. Установка нового значения. Метод __setitem__()
Метод __setitem__() вызывается, когда нужно записать данные по индексу в объект класса. Этот объект класса является, как правило, списком, кортежем и т.п. Использование метода __setitem__() в классе может быть примерно таким
def ClassName: # Составляющие класса ... def __setitem__(self, index, newValue): self.objName[index] = newValue
здесь
- ClassName – имя класса;
- objName – имя итерированного объекта для которого устанавливается значение newValue в позиции index;
- index – позиция (индекс) начинающаяся с 0;
- newValue – новое значение, устанавливаемое в объекте objName.
После реализации метода __setitem__() в классе можно записывать данные в итерированный объект класса. Это выглядит приблизительно так
ClassName[index] = newValue
здесь
- ClassName – имя класса содержащего итерированный объект;
- index – позиция элемента в итерированном объекте;
- newValue – новое значение.
⇑
3. Пример, демонстрирующий реализацию массива комплексных чисел и доступ по индексу к элементам массива
В примере объявляется класс ArrayComplex, содержащий следующие составляющие:
- AC – имя массива комплексных чисел. Массив организован в виде списка. Каждый элемент массива представляет пару (re, im), являющуюся кортежем;
- __init__() – конструктор. Создает пустой список AC;
- метод Add() – обеспечивает добавление нового комплексного числа в массив. Число прилагается как кортеж вида (re, im), состоящий из действительной части комплексного числа (re) и мнимой части комплексного числа (im);
- метод Count() – возвращает длину списка AC;
- метод Print() – выводит список комплексных чисел в удобном виде;
- метод __getitem__() – обеспечивает чтение по индексу элемента списка AC;
- метод __setitem__() – обеспечивает запись в список чисел AC заданного значения в заданной позиции (индексе).
# Доступ по индексу. Перегрузка методов __getitem__(), __setitem__() # Класс, реализующий массив комплексных чисел class ArrayComplex: # 1. Конструктор класса def __init__(self): # массив реализован в виде списка с именем AC self.AC = [] # создать пустой список return # 2. Метод, добавляющий комплексное число к списку. # Число добавляется в виде кортежа. # Здесь re - вещественная часть комплексного числа, # im - мнимая часть комплексного числа. def Add(self, re, im): self.AC = self.AC + [(re, im)] # 3. Метод, возвращающий количество элементов массива def Count(self): return len(self.AC) # 4. Метод, выводящий список комплексных чисел на экран def Print(self, msg): s = msg + " => [ " for c in self.AC: s = s + "(" + str(c[0]) + ", " + str(c[1]) + ") " s = s + "]" print(s) # 5. Методы, обеспечивающие доступ по индексу [] # 5.1. Чтение элемента массива по индексу def __getitem__(self, index): return self.AC[index] # 5.2. Запись элемента по индексу, # значение value - это кортеж типа (re, im) def __setitem__(self, index, value): self.AC[index] = value # ------- Использование класса ------- # 1. Создать объект класса ArrayComplex AC = ArrayComplex() # 2. Добавить несколько чисел AC.Add(5, 8) AC.Add(2, -4) AC.Add(-3.5, -1.8) AC.Add(2.8, 1) # 3. Вывести содержимое объекта AC AC.Print("AC") # 4. Прочитать первый элемент массива cm1 = AC[0] # викликається AC.__getitem__(0) print("cm1 = ", cm1) # Прочесть последний элемент массива cm2 = AC[AC.Count()-1] print("cm2 = ", cm2) # 5. Записать новое значение в массив в позиции 1 AC[1] = (10, 20) # вызывается AC.__setitem__(1, (10, 20)) # 6. Повторно вывести массив AC.Print("AC") # 7. Получить объект среза и вывести срез objSlice = AC[:AC.Count()] print("Slice[:Count()-1] => ", objSlice) # 8. Получить срез, содержащий первые 2 элемента objSlice = AC[:3] print("Slice[:2] => ", objSlice)
Результат
AC => [ (5, 8) (2, -4) (-3.5, -1.8) (2.8, 1) ] ('cm1 = ', (5, 8)) ('cm2 = ', (2.8, 1)) AC => [ (5, 8) (10, 20) (-3.5, -1.8) (2.8, 1) ] ('Slice[:Count()-1] => ', [(5, 8), (10, 20), (-3.5, -1.8), (2.8, 1)]) ('Slice[:2] => ', [(5, 8), (10, 20), (-3.5, -1.8)])
⇑
4. Пример, демонстрирующий доступ к объекту класса по индексу. Реализация классов Point и ListPoints
# Доступ по индексу # Класс, описывающий точку на координатной плоскости, # в классе используются внутренние поля x, y class Point: # 1. Конструктор класса def __init__(self, x, y): self.x = x self.y = y return # 2. Методы доступа # 2.1. Установить новое значение x def SetXY(self, x, y): self.x = x self.y = y return # 2.2. Считать x, y def X(self) : return self.x def Y(self) : return self.y # Метод, выводящий точку на экран def Print(self, msg): s = msg + " = (" + str(self.x) + "; " + str(self.y) + ")"; print(s) # Класс, описывающий массив точек, имеющий имя AP class ListPoints: # конструктор def __init__(self): self.AP = [] # Создать пустой список # Метод, додающий точку в конец списка def Add(self, pt): self.AP = self.AP + [pt] # Метод возвращающий список точек def GetList(self): return self.AP # Метод, который выводит список точек def Print(self, msg): s = msg + " = [" # сформировать строку вывода for p in self.AP: s = s + "(" + str(p.X()) + "; " + str(p.Y()) + ") " print(s + ']\n') # Методы, реализующие доступ по индексу # Получить точку по индексу index def __getitem__(self, index): return self.AP[index] # Записать новую точку в позиции index def __setitem__(self, index, value): self.AP[index] = value # ------- Использование классов Point и ListPoints ------- # 1. Создать некоторую точку p1 = Point(2, 8.3) p1.Print("p1") # 2. Создать массив точек типа Point # 2.1. Создать пустой массив ArrayPoints = ListPoints() # 2.2. Добавить к массиву 3 точки ArrayPoints.Add(p1) # Добавить точку p1 ArrayPoints.Add(Point(3, 7.1)) # добавить точку (3, 7.1) ArrayPoints.Add(Point(2, 1.6)) # 2.3. Вывести массив точек ArrayPoints.Print("ArrayPoints") # 3. Считать точку с индексом 0 pt = ArrayPoints[0] # здесь вызывается метод __getitem__() pt.Print("ArrayPoints[0]") # 4. Записать новое значение в точку с индексом 1 ArrayPoints[1] = Point(1.5, 2.3) # вызывается метод __setitem__() # 5. Вывести массив заново ArrayPoints.Print("ArrayPoints")
Результат
p1 = (2; 8.3) ArrayPoints = [(2; 8.3) (3; 7.1) (2; 1.6) ] ArrayPoints[0] = (2; 8.3) ArrayPoints = [(2; 8.3) (1.5; 2.3) (2; 1.6) ]
⇑
Связанные темы
⇑