Согласитесь, что использовать операторы куда удобнее, чем обыкновенные методы. Давайте вспомним о реализованном нами методе move(x, y)
и напишем ему альтернативу в виде операторов +
и +=
.
При выполнении кода point + (x, y)
, создаётся новая точка, которая отличается от изначальной на заданное кортежем расстояние по осям x и y.
При выполнении кода point += (x, y)
производится перемещение изначальной точки.
Напомним, что сейчас мы модернизируем только класс PatchedPoint
.
Примечание
Ваше решение должно содержать только классы и функции.
В решении не должно быть вызовов инициализации требуемых классов.
Пример
Ввод
point = PatchedPoint()
print(point)
new_point = point + (2, -3)
print(point, new_point, point is new_point)
Вывод
(0, 0)
(0, 0) (2, -3) False
Ввод
first_point = second_point = PatchedPoint((2, -7))
first_point += (7, 3)
print(first_point, second_point, first_point is second_point)
Вывод
(9, -4) (9, -4) True
Решение
Настала очередь попробовать волшебные методы __add__ и __iadd__. Первый реализует операцию +, второй – +=. И как и в прошлой задаче эти методы имеют определенную разницу не только с точки зрения нотации, но и с точки зрения того, что мы получаем в результате. Важное отличие в том, что __add__ должен ввернуть новый объект, никак не связанный ни с первым, ни вторым, в то время как __iadd__ модифицирует первый объект. И этот нюанс иногда вызывает сложность, если модификация объекта не представляет никаких проблем, мы это уже делали несколько раз в прошлых задачах, то порождение нового, не всегда очевидная задача для начинающих программистов просто в силу ловушки нашего привычного хода мыслей. В то же время это элементарное действие – для порождения нового объекта достаточно его инициализировать нужными значениями и вернуть в качестве результата.
Посмотреть код
Решение
class Point:
def __init__(self, x, y) -> None:
self.x = x
self.y = y
def move(self, new_x, new_y):
self.x += new_x
self.y += new_y
def length(self, point):
result = ((point.x - self.x) ** 2 + (point.y - self.y) ** 2) ** 0.5
return round(result, 2)
class PatchedPoint(Point):
def __init__(self, *args) -> None:
match len(args):
case 0:
self.x = 0
self.y = 0
case 1:
self.x, self.y = args[0]
case 2:
self.x, self.y = args
def __add__(self, other):
return PatchedPoint(self.x + other[0], self.y + other[1])
def __iadd__(self, other):
self.move(other[0], other[1])
return self
def __str__(self) -> str:
string = f'({self.x}, {self.y})'
return string
def __repr__(self) -> str:
string = f'PatchedPoint({self.x}, {self.y})'
return string
Решение
class Point:
def __init__(self, x, y) -> None:
self.x = x
self.y = y
def move(self, new_x, new_y):
self.x += new_x
self.y += new_y
def length(self, point):
result = ((point.x - self.x) ** 2 + (point.y - self.y) ** 2) ** 0.5
return round(result, 2)
class PatchedPoint(Point):
def __init__(self, *args) -> None:
match len(args):
case 0:
super().__init__(0, 0)
case 1:
super().__init__(*args[0])
case 2:
super().__init__(*args)
def __add__(self, other):
return PatchedPoint(self.x + other[0], self.y + other[1])
def __iadd__(self, other):
self.move(other[0], other[1])
return self
def __str__(self) -> str:
string = f'({self.x}, {self.y})'
return string
def __repr__(self) -> str:
string = f'PatchedPoint({self.x}, {self.y})'
return string