У Python ми можемо змінити спосіб роботи операторів з користувацькими типами даних. Наприклад, ми можемо зробити так, щоб оператор + виконував арифметичне додавання двох чисел або об’єднання двох списків або конкатенацію двох рядків.
Ця можливість в Python, що дозволяє одному і тому ж оператору виконувати різні дії в залежності від контексту, називається перевантаженням оператора.
Спеціальні функції в Python
Функції класу, що починаються з подвійного підкреслення __, називаються спеціальними функціями в Python. Спеціальні функції визначаються інтерпретатором Python і використовуються для реалізації певних можливостей чи поведінки.
Вони називаються “функціями з подвійним підкресленням”, тому що мають префікс та суфікс у вигляді подвійного підкреслення, наприклад __init__() або __add__().
Ось деякі зі спеціальних функцій, які доступні в Python:
| Функція | Опис |
| __init__() | Ініціалізує атрибути об’єкта. |
| __str__() | Повертає рядкове представлення об’єкта. |
| __len__() | Повертає довжину об’єкта. |
| __add__() | Додає два об’єкти. |
| __call__() | Викликає об’єкти класу як звичайна функція. |
Приклад перевантаження оператора в Python
Розглянемо приклад перевантаження оператора + в Python. Для цього нам необхідно визначити у класі функцію __add__().
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __str__(self): return "({0},{1})".format(self.x, self.y) def __add__(self, other): x = self.x + other.x y = self.y + other.y return Point(x, y) p1 = Point(1, 2) p2 = Point(2, 3) print(p1 + p2) |
Результат:
(3,5)
Коли ми виконуємо p1 + p2, Python викликає метод p1.__add__(p2), який, в свою чергу, є Point.__add__(p1,p2). Після цього операція додавання виконується так, як ми вказали.
Аналогічно ми можемо перевантажувати й інші оператори. Нижче наведено таблицю спеціальних функцій, які можна перевантажити.
| Оператор | Вираз | Всередині |
| Додавання (+) | p1 + p2 | p1.__add__(p2) |
| Віднімання (-) | p1 – p2 | p1.__sub__(p2) |
| Множення (*) | p1 * p2 | p1.__mul__(p2) |
| Піднесення до степеня (**) | p1 ** p2 | p1.__pow__(p2) |
| Ділення (/) | p1 / p2 | p1.__truediv__(p2) |
| Ділення з відкиданням дробової частини (//) | p1 // p2 | p1.__floordiv__(p2) |
| Залишок від ділення (%) | p1 % p2 | p1.__mod__(p2) |
| Побітовий зсув вліво (<<) | p1 << p2 | p1.__lshift__(p2) |
| Побітовий зсув вправо (>>) | p1 >> p2 | p1.__rshift__(p2) |
| Побітове І (&) | p1 & p2 | p1.__and__(p2) |
| Побітове АБО (|) | p1 | p2 | p1.__or__(p2) |
| Побітове Виключне АБО (^) | p1 ^ p2 | p1.__xor__(p2) |
| Побітове НЕ (~) | ~p1 | p1.__invert__() |
Перевантаження операторів порівняння в Python
Python не обмежується можливістю перевантаження тільки арифметичних операторів. Ми можемо перевантажувати й оператори порівняння.
Ось приклад перевантаження оператора < для порівняння двох об’єктів класу Person на основі їх віку (члена age):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Person: def __init__(self, name, age): self.name = name self.age = age # Перегрузка оператора < def __lt__(self, other): return self.age < other.age p1 = Person("Alice", 20) p2 = Person("Bob", 30) print(p1 < p2) # виведе True print(p2 < p1) # виведе False |
Результат:
True
False
Тут метод __lt__() перевантажує оператор < для порівняння члена age двох об’єктів.
Метод __lt__() повертає:
True, якщо age першого об’єкта менше age другого об’єкта;
False, якщо age першого об’єкта більше age другого об’єкта.
Список операторів порівняння, які можна перевантажити в Python:
| Оператор | Вираз | Всередині |
| Менше ніж (<) | p1 < p2 | p1.__lt__(p2) |
| Менше або Дорівнює (<=) | p1 <= p2 | p1.__le__(p2) |
| Дорівнює (==) | p1 == p2 | p1.__eq__(p2) |
| Не дорівнює (!=) | p1 != p2 | p1.__ne__(p2) |
| Більше ніж (>) | p1 > p2 | p1.__gt__(p2) |
| Більше або Дорівнює (>=) | p1 >= p2 | p1.__ge__(p2) |
