- Перегрузка оператора в Python
- Пример перегрузки оператора
- Список математических операторов
- Перегрузка операторов отношения
- Другие операторы отношения
- Перегрузка операторов в Python
- Специальные функции
- Перегрузка оператора +
- Перегрузка операторов в Python
- Различные варианты использования основных арифметических операторов
- Как перегрузить оператор в Python?
- Специальные функции в Python
- Для двоичных операторов в Python
- Для операторов сравнения в Python
- Для операторов присваивания
- Для унарных операторов
- Перегрузка бинарного оператора
- Перегрузка операторов сравнения
- Пример
Перегрузка оператора в Python
Перегрузка операторов в Python позволяет нам использовать математические, логические и побитовые операторы для объектов, как и любой примитивный тип данных.
Например, вы можете легко сложить два числа 3 и 5 с помощью оператора +, т.е. 3 + 5. И результат будет 8.
Но что, если вы хотите добавить два круга (объект класса Circle) и создать круг с двойным радиусом? Или что, если вы хотите добавить две точки декартовой сетки, чтобы получить еще одну точку с тем же оператором «+»? Перегрузка операторов Python позволяет выполнять такие же операции.
Пример перегрузки оператора
Теперь давайте посмотрим на пример перегрузки математического оператора.
class GridPoint: #Line: 1, Declaring a class def __init__(self, x, y): self.x = x self.y = y #Line: 4 def __add__(self, other): # Equivalent of + operator return GridPoint(self.x + other.x, self.y + other.y) def __str__(self): #Line: 12, returns the attributes when the object is printed string = str(self.x) string = string + ", " + str(self.y) return string #Line: 12 point1 = GridPoint(3, 5) #Line: 14 Creating a grid point point2 = GridPoint(-1, 4) #Line: 15, Creating another point point3 = point1 + point2 #Line: 16, Add two points using __add__() method print(point3) #Line: 17, Print the attributes using __str__() method
Строки с 1 по 4 указывают объявление класса GridPoint и определение метода конструктора. Давайте посмотрим на строки 6 и 7.
def __add__(self, other): # Equivalent of + operator return GridPoint(self.x + other.x, self.y + other.y)
Когда мы используем оператор ‘+’ в качестве операции математического сложения, неявно вызывается метод __add __().
Итак, если мы хотим добавить два объекта класса GridPoint, мы должны заново определить этот метод. Итак, здесь нам нужно создать еще один экземпляр класса GridPoint, значение x которого является суммой x в двух экземплярах GridPoint вокруг оператора ‘+’, а значение y также является суммированием y в двух экземплярах GridPoint вокруг ‘ + ‘оператор.
Строки с 9 по 12 определяют метод __str __(), который вызывается, когда мы пытаемся напечатать объект. Это тоже встроенный метод. Но мы собираемся перегрузить метод, чтобы он печатал в нашем указанном формате.
В строках 14 и 15 мы создали два объекта GridPoint, а именно point1 и point2. Теперь посмотрите Строку 16. Два экземпляра класса GridPoint добавляются с помощью оператора «+» и назначаются, как другой экземпляр GridPoint. В этом вам поможет перегрузка операторов Python. Так что не удивляйтесь, когда 17-я строка покажет результат, как на изображении ниже.
Список математических операторов
Вот список операторов, которые можно перегрузить и аналогичным образом использовать с перегрузкой операторов.
Оператор | Описание | Метод |
+ | Дополнение | __add __ (self, other) |
— | Вычитание | __sub __ (self, other) |
* | Умножение | __mul __ (self, other) |
/ | Истинное деление | __truediv __ (self, other) |
// | Подразделение этажей | __floordiv __ (self, other) |
% | Остаток | __mod __ (self, other) |
** | Мощность | __pow __ (self, other) |
& | Побитовое AND | __and __ (self, other) |
| | Побитовое OR | __or __ (self, other) |
^ | Побитовое исключающее XOR | __xor __ (self, other) |
Перегрузка операторов отношения
Операторы отношения перегружаются в Python очень похожим образом. Но разница в том, что эти операторы часто возвращают true и false вместо другого экземпляра объекта. Давайте работать с примером.
class GridPoint: def __init__(self, x, y): self.x = x self.y = y def __gt__(self, other): # Overloading the greater than operator return self.x > other.x # Returns true if value of x in the left operand is greater than that in the right one. Returns false otherwise def __str__(self): string = str(self.x) string = string + ", " + str(self.y) return string point1 = GridPoint(3, 5) point2 = GridPoint(-1, 4) if point1 > point2: # Compares with the overloaded __gt__() method print('point1 is greater than point2') else: print('point1 is not greater than point2')
Посмотрите на строку 6, где загружен оператор «больше». Обычный оператор ‘>’ возвращает истину, если операнд в его левой части больше, чем в правом. Мы собираемся использовать это свойство для сравнения двух экземпляров класса GridPoint.
Затем в строке 17 мы сравниваем объекты класса GridPoint, чтобы получить значение логического типа, которое определит, имеет ли первый объект большее значение «x». В этом случае реляционный оператор возвращает истину, поскольку 3 больше -1. В результате программа выдает «точка1 больше точки2».
Другие операторы отношения
Вот список реляционных операторов, которые можно перегрузить таким же образом.
Оператор | Описание | Метод |
> | Больше, чем | __gt __ (self, other) |
> = | Больше или равно | __ge __ (self, other) |
Меньше, чем | __lt __ (self, other) | |
Меньше или равно | __le __ (self, other) | |
== | Равно | __eq __ (self, other) |
!= | Не равно | __ne __ (self, other) |
Перегрузка операторов в Python
Один и тот же оператор в Python по-разному ведет себя с разными типами. Например, оператор + в зависимости от типа операндов может складывать 2 числа, сливать 2 списка или объединять 2 строки. Когда-нибудь задумывались, почему так происходит? Дело в перегрузке операторов в Python.
Перегрузка оператора — это возможность переопределять различные операторы в классах, то есть менять операции, которые они выполняют, в зависимости от контекста.
Давайте рассмотрим пользовательский класс Point . Он должен моделировать точку в двумерной системе координат.
class Point: def __init__(self, x=0, y=0): self.x = x self.y = y # задаем координаты точек p1, p2 p1 = Point(1, 2) p2 = Point(2, 3) # пытаемся вывести сумму точек print(p1+p2)
Traceback (most recent call last):
File "", line 9, in
print(p1+p2)
TypeError: unsupported operand type(s) for +: 'Point' and 'Point'
Python не знает, как «складывать» два объекта Point . Чтобы объяснить ему это, нужно задать поведение оператора + с операндами этого типа.
Тут-то и понадобится перегрузка оператора. Но сначала давайте познакомимся со специальными функциями в Python. Это поможет понять, как работает перегрузка операторов.
Специальные функции
Специальные функции классов начинаются с двойного подчеркивания __ . Их еще называют магическими методами.
Это не обычные методы, которые мы определяем в классе. В коде выше мы уже использовали специальную функцию __init__() . Она вызывается каждый раз, когда мы создаем новый объект класса Point .
С помощью специальных методов можно сделать наш класс совместимым со встроенными функциями.
Мы хотим, чтобы функция print() выводила на экран координаты объекта Point. Сейчас print( ) печатает что-то не то. Мы можем определить метод __str__() в нашем классе, который будет контролировать правильный вывод объекта. Давайте посмотрим, как это сделать.
class Point: def __init__(self, x = 0, y = 0): self.x = self.y = y def __str__(self): return "(,)".format(self.x,self.y)
class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __str__(self): return "(, )".format(self.x, self.y) # задаем координаты точки p1 p1 = Point(2, 3) # выводим точку — ее координаты print(p1)
Так-то лучше. Но оказывается, когда мы используем встроенные функции str() или format() , вызывается этот же метод.
Теперь, когда вы используете str(p1) или format(p1) , Python вызывает специальный метод p1.__str__() .
Давайте вернемся к перегрузке операторов.
Перегрузка оператора +
Чтобы перегрузить оператор + , нам нужно реализовать специальный метод __add__() в нашем классе. Внутри него мы можем делать все, что захотим. Но разумнее будет вернуть объект Point в виде координатной суммы. Так и сделаем.
class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __str__(self): return "(,)".format(self.x, self.y) def __add__(self, other): x = self.x + other.x y = self.y + other.y return Point(x, y)
Теперь еще раз попробуем операцию сложения.
class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __str__(self): return "(,)".format(self.x, self.y) def __add__(self, other): x = self.x + other.x y = self.y + other.y return Point(x, y) # задаем координаты точек p1, p2 p1 = Point(1, 2) p2 = Point(2, 3) print(p1+p2)
Когда мы используем p1 + p2 , Python вызывает p1.__add__(p2) , а тот, в свою очередь, вызывает Point.__add__(p1,p2) . После этого операция сложения выполняется указанным нами способом.
Точно так же мы можем перегрузить и другие операторы. Вот, какие для этого понадобятся специальные функции:
Специальная функция
Перегрузка операторов в Python
Перегрузка оператора — это явление придания альтернативного значения действию, выполняемому оператором за пределами их предопределенной операционной функции. Перегрузка оператора также называется специализированным полиморфизмом оператора.
Операторы Python работают для встроенных классов. Но один и тот же оператор по-разному выражает разные типы. Например, оператор + выполнит арифметическое сложение двух чисел, объединит два списка и объединит две строки. Python позволяет одному и тому же оператору иметь разные значения в зависимости от контекста ссылки.
Различные варианты использования основных арифметических операторов
# Program to show use of # + operator for different purposes. print(5 + 5) # concatenate two strings print("Safa"+"Mulani") # Product two numbers print(10 * 10) # Repeat the String print("Safa"*4)
10 SafaMulani 100 SafaSafaSafaSafa
Как перегрузить оператор в Python?
Для выполнения перегрузки оператора Python предоставляет некоторую специальную функцию, которая автоматически вызывается, когда она связана с этим конкретным оператором. Например, когда мы используем оператор +, автоматически вызывается метод __add__ , в котором определяется операция для оператора +.
Специальные функции в Python
Глобальные функции, начинающиеся с двойного подчеркивания __, в Python называются специальными функциями. Это потому, что они необычные. Одна из них — функция __init __(), которую мы обычно определяем и напоминаем как конструктор. Он вызывается каждый раз, когда мы создаем новый объект этого класса.
Для двоичных операторов в Python
Оператор | Метод |
---|---|
+ | __add__(self, other) |
– | __sub__(self, other) |
* | __mul__(self, other) |
/ | __truediv__(self, other) |
// | __floordiv__(self, other) |
% | __mod__(self, other) |
** | __pow__(self, other) |
Для операторов сравнения в Python
Оператор | Метод |
---|---|
__lt__(self, other) | |
> | __gt__(self, other) |
__le__(self, other) | |
>= | __ge__(self, other) |
== | __eq__(self, other) |
!= | __ne__(self, other) |
Для операторов присваивания
Оператор | Метод |
---|---|
-= | __isub__(self, other) |
+= | __iadd__(self, other) |
*= | __imul__(self, other) |
/= | __idiv__(self, other) |
//= | __ifloordiv__(self, other) |
%= | __imod__(self, other) |
**= | __ipow__(self, other) |
Для унарных операторов
Перегрузка бинарного оператора
Когда мы используем оператор +, автоматически вызывается волшебный метод __add__ , в котором определяется операция для оператора +. Следовательно, изменяя код метода, мы можем придать альтернативное значение оператору +.
# Program to overload an binary + operator class X: def __init__(self, x): self.x = x # adding two objects def __add__(self, y): return self.x + y.x ob1 = X(5) ob2 = X(5) ob3 = X("Safa") ob4 = X("Mulani") print(ob1 + ob2) # simple addition of objects print(ob3 + ob4) # concatenation of strings through object addition
Перегрузка операторов сравнения
class X: def __init__(self, x): self.x = x def __lt__(self, other): # Overloading < operator if(self.x ob1 is less than ob2 Not equalПример
class Animal: def __init__(self, age): self.__age = age def setage(self, age): self.__age = age def getage(self): return self.__age def __add__(self, predict): return Animal( self.__age + predict.__age ) def __gt__(self, predict): return self.__age > predict.__age def __lt__(self, predict): return self.__age < predict.__age def __str__(self): return "Animal with original age " + str(self.__age) c1 = Animal(5) print(c1.getage()) c2 = Animal(5) print(c2.getage()) c3 = c1 + c2 print(c3.getage()) print( c3 >c2) print( c1 < c2) print(c3)5 5 10 True False Animal with original age 10