Перевантаження скорочених операторів присвоєння
Перед вивченням даної теми рекомендується ознайомитись з наступною темою:
Пошук на інших ресурсах:
Зміст
- 1. Особливості перевантаження скорочених операторів присвоєння +=, -=, *=, /=, %=, //=
- 2. Перевантаження скорочених операторів присвоєння. Клас Fraction (дріб)
- 3. Приклад перевантаження скорочених операторів присвоєння. Класи Point та ArrayPoint. Оперування масивом точок
- Споріднені теми
1. Особливості перевантаження скорочених операторів присвоєння +=, -=, *=, /=, %=, //=
Для перевантаження скорочених операторів присвоєння у класі потрібно оголосити наступні методи:
- __iadd__() – перевантажує скорочений оператор присвоєння +=;
- __isub__() – перевантажує оператор -=;
- __imul__() – перевантажує оператор *=;
- __idiv__() – перевантажує оператор /=;
- __ifloordiv__() – перевантажує оператор //=;
- __imod__() – перевантажує оператор %=.
Реалізація кожного з цих методів у класі потребує отримання двох параметрів:
- параметру типу self – поточний об’єкт класу (this);
- параметру, що має тип даного класу. Цей параметр є об’єктом, який використовується у правій частині скороченого оператора присвоєння.
Після того, як у деякому класі реалізовано методи, що перевантажують один зі скорочених операторів присвоєння, над об’єктами цього класу можна виконувати наступні дії
obj1 op obj2
тут
- obj1, obj2 – об’єкти класу;
- op – одна з операцій +=, -=, *=, /=, //=, %=.
Наприклад, для перевантаження оператора += в класі A може бути приблизно наступний код
class A: # ... # перевантаження оператора += def __iadd__(self, obj): # Дії, що потрібно виконати # ... # Виклик перевантаженого оператора += obj1 = A() obj2 = A() obj1 += obj2
⇑
2. Перевантаження скорочених операторів присвоєння. Клас Fraction (дріб)
У прикладі оголошується клас Fraction (дріб). У класі оголошуються дві внутрішні змінні:
- num (self.num) – чисельник дробу;
- denom (self.denom) – знаменник дробу.
У класі Fraction демонструється перевантаження методів +=, -=, *=, /=, %=, //=.
# Перевантаження операторів +=, -=, *=, /=, %=, //= # Клас, що описує дріб, який заданий чисельником та знаменником: # - num - чисельник; # - denom - знаменник. class Fraction: # Конструктор класу, num - чисельник, denom - знаменник def __init__(self, num, denom): self.num = num self.denom = denom # Корегування num, denom if self.num == 0: self.num = 1 if self.denom == 0: self.denom = 1 self.Normal() return #-------------- Методи перевантаження операторів -------------- # Перевантаження оператора += # Додавання до даного дробу іншого дробу - метод __iadd__() def __iadd__(self, frac): obj = Fraction((self.num*frac.denom+self.denom*frac.num), self.denom*frac.denom) return obj # Перевантаження оператора -= # Віднімання від даного дробу іншого дробу - метод __isub__() def __isub__(self, frac): # віднімання дробів obj = Fraction((self.num*frac.denom-self.denom*frac.num), self.denom*frac.denom) return obj # Перевантаження оператора *= - метод __imul__() def __imul__(self, frac): obj = Fraction(self.num*frac.num, self.denom*frac.denom) return obj # Перевантаження оператора /= - метод __idiv__() def __idiv__(self, frac): obj = Fraction(self.num*frac.denom, self.denom*frac.num) return obj # Перевантаження оператора //= - метод __ifloordiv__() def __ifloordiv__(self, frac): # Метод повертає результат ділення дробів так само як і метод idiv() return Fraction(self.num*frac.denom, self.denom*frac.num) # Перевантаження оператора %= - метод __imod__() def __imod__(self, frac): # Метод повертає інвертований дріб: 5/6 => 6/5 return Fraction(self.denom, self.num) # --------------------------------------------------------- # Метод, що виводить значення внутрішніх координат x, y def Print(self, msg): print(msg, " => ", self.num, " / ", self.denom) return # Метод, що нормалізує дріб 8/12 => 2/3 def Normal(self): t = abs(self.num) i = 1 num = i while i <= t: if ((self.num%i) == 0) and ((self.denom%i) == 0): num = i i = i+1 self.num = self.num / num self.denom = self.denom / num # (-num)/(-denom) => num/denom if (self.num<0) and (self.denom<0): self.num = -self.num self.denom = -self.denom return # Тестування f1 = Fraction(1, 2) # конструктор f1.Print("f1") f2 = Fraction(2, 3) # конструктор f2.Print("f2") f1 += f2 # метод __iadd__() f1.Print("f1+=f2") f1 -= f2 # метод __isub__() f1.Print("f1-=f2") f1 *= f2 # метод __imul__() f1.Print("f1*=f2") f1 /= f2 # метод __idiv__() f1.Print("f1/=f2") f1 //=f2 # метод __ifloordiv__() f1.Print("f1//f2") f1 %= f1 # метод __imod__() f1.Print("f1%=f1")
Результат
f1 => 1 / 2) f2 => 2 / 3) f1+=f2 => 7 / 6 f1-=f2 => 1 / 2) f1*=f2 => 1 / 3) f1/=f2 => 1 / 2) f1//f2 => 3 / 4) f1%=f1 => 4 / 3)
⇑
3. Приклад перевантаження скорочених операторів присвоєння. Класи Point та ArrayPoint. Оперування масивом точок
У прикладі оголошуються класи Point та ArrayPoint. Клас Point описує точку на координатній площині. Клас ArrayPoint описує масив точок типу Point. Масив реалізований у вигляді списку.
У класі ArrayPoint перевантажується скорочений оператор присвоєння +=, який реалізує конкатенацію масивів типу ArrayPoint.
# Перевантаження оператору += для додавання списків об'єктів # Клас, що описує точку на координатній площині (x; y) class Point: # Конструктор def __init__(self, x, y): self.x = x self.y = y # Методи, що повертають координати точки def GetX(self): return self.x def GetY(self): return self.y # Метод, що виводить координати точки def Print(self, msg): print(msg, "=> (", self.x, "; ", self.y, ")") # Клас, що реалізує масив точок: # - AP - масив точок. # У класі перевантажується оператор +=, який # робить конкатенацію двох масивів точок. class ArrayPoint: # Конструктор 2 - створює пустий масив def __init__(self): self.AP = [] # масив у вигляді списку # Метод, що додає елемент до масиву def Add(self, pt): self.AP = self.AP + [pt] # Метод, що повертає масив self.AP def Get(self): return self.AP # Метод, що виводить масив точок def Print(self, msg): print(msg) for pt in self.AP: pt.Print("") # Метод, що перевантажує оператор +=, # метод додає до масиву self.AP точок інший масив def __iadd__(self, AP2): # 1. Об'єднати списки двох об'єктів lst = self.AP + AP2.Get() # 2. Створити результуючий об'єкт obj = ArrayPoint() # 3. Додати до об'єкту obj елементи списку for t in lst: obj.Add(t) # Повернути результуючий об'єкт return obj # Тест # 1. Створити масив точок AP1 AP1 = ArrayPoint() AP1.Add(Point(2, 3)) AP1.Add(Point(4, 7)) AP1.Add(Point(8, 3)) AP1.Print("AP1") # 2. Створити масив точок AP2 AP2 = ArrayPoint() AP2.Add(Point(-2, 4)) AP2.Add(Point(7, 6)) AP2.Print("AP2") # 3. Додати масиви AP1 += AP2 AP1.Print("AP1 += AP2")
Результат
AP1 ('', '=> (', 2, '; ', 3, ')') ('', '=> (', 4, '; ', 7, ')') ('', '=> (', 8, '; ', 3, ')') AP2 ('', '=> (', -2, '; ', 4, ')') ('', '=> (', 7, '; ', 6, ')') AP1 += AP2 ('', '=> (', 2, '; ', 3, ')') ('', '=> (', 4, '; ', 7, ')') ('', '=> (', 8, '; ', 3, ')') ('', '=> (', -2, '; ', 4, ')') ('', '=> (', 7, '; ', 6, ')')
⇑
Споріднені теми
- Перевантаження операторів. Загальні відомості. Методи, що перевантажують оператори. Приклади
- Доступ до елементів за індексом. Методи __getitem__() та __setitem()__
- Перевантаження бінарних арифметичних операторів: +, –, *, /, //, %
⇑