Претоварване на оператора на Python

Можете да промените значението на оператор в Python в зависимост от използваните операнди. В този урок ще научите как да използвате претоварване на оператор в Python обектно-ориентирано програмиране.

Претоварване на оператора на Python

Операторите на Python работят за вградени класове. Но един и същ оператор се държи различно при различните типове. Например, +операторът ще извърши аритметично събиране на две числа, ще обедини два списъка или ще обедини два низа.

Тази функция в Python, която позволява на един и същ оператор да има различно значение според контекста, се нарича претоварване на оператора.

И така, какво се случва, когато ги използваме с обекти от дефиниран от потребителя клас? Нека разгледаме следния клас, който се опитва да симулира точка в 2-D координатна система.

 class Point: def __init__(self, x=0, y=0): self.x = x self.y = y p1 = Point(1, 2) p2 = Point(2, 3) print(p1+p2)

Изход

 Проследяване (последно последно повикване): Файл "", ред 9, в печат (p1 + p2) TypeError: неподдържан (и) тип (операнди) за +: 'Point' и 'Point'

Тук можем да видим, че a TypeErrorе повдигнато, тъй като Python не е знаел как да добавя два Pointобекта заедно.

Въпреки това, можем да постигнем тази задача в Python чрез претоварване на оператора. Но първо, нека да добием представа за специалните функции.

Специални функции на Python

Функциите на класа, които започват с двойно подчертаване, __се наричат ​​специални функции в Python.

Тези функции не са типичните функции, които дефинираме за клас. Най __init__()функцията ние определено по-горе е един от тях. Той се извиква всеки път, когато създаваме нов обект от този клас.

Има много други специални функции в Python. Посетете специалните функции на Python, за да научите повече за тях.

Използвайки специални функции, можем да направим класа си съвместим с вградените функции.

 >>> p1 = Point(2,3) >>> print(p1) 

Да предположим, че искаме print()функцията да отпечатва координатите на Pointобекта вместо това, което имаме. Можем да дефинираме __str__()метод в нашия клас, който контролира начина на отпечатване на обекта. Нека да разгледаме как можем да постигнем това:

 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)

Сега нека опитаме print()функцията отново.

 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) p1 = Point(2, 3) print(p1)

Изход

 (2, 3)

Това е по-добре. Оказва се, че същият този метод се извиква, когато използваме вградената функция str()или format().

 >>> str(p1) '(2,3)' >>> format(p1) '(2,3)'

Така че, когато използвате 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 "((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)

Сега нека опитаме операцията по добавяне отново:

 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)
Побитово XOR p1 p2 p1.__xor__(p2)
Побитово НЕ ~p1 p1.__invert__()

Претоварване на оператори за сравнение

Python не ограничава претоварването на оператора само до аритметични оператори. Можем да претоварим и операторите за сравнение.

Да предположим, че искахме да приложим символа с по-малко от <символ в нашия Pointклас.

Let us compare the magnitude of these points from the origin and return the result for this purpose. It can be implemented as follows.

 # overloading the less than operator 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 __lt__(self, other): self_mag = (self.x ** 2) + (self.y ** 2) other_mag = (other.x ** 2) + (other.y ** 2) return self_mag < other_mag p1 = Point(1,1) p2 = Point(-2,-3) p3 = Point(1,-1) # use less than print(p1 

Output

 True False False

Similarly, the special functions that we need to implement, to overload other comparison operators are tabulated below.

Operator Expression Internally
Less than p1 < p2 p1.__lt__(p2)
Less than or equal to p1 <= p2 p1.__le__(p2)
Equal to p1 == p2 p1.__eq__(p2)
Not equal to p1 != p2 p1.__ne__(p2)
Greater than p1> p2 p1.__gt__(p2)
Greater than or equal to p1>= p2 p1.__ge__(p2)

Интересни статии...