+
) используется метод __add__(self, other)
, для вычитания (-
) - __sub__(self, other)
и т.д. Чтобы переопределить оператор в наследуемом классе, нужно просто определить соответствующий магический метод в этом классе. Пример:
class Parent:
def __init__(self, value):
self.value = value
def __add__(self, other):
return Parent(self.value + other.value)
class Child(Parent):
def __add__(self, other):
return Child(self.value - other.value) #Переопределенная логика
В Python переопределение операторов в наследуемых классах (также известное как "перегрузка операторов") достигается путем определения специальных методов (magic methods) с предопределенными именами, начинающимися и заканчивающимися на два подчеркивания. Эти методы соответствуют конкретным операторам.
Когда вы используете оператор с объектами пользовательского класса, Python ищет соответствующий специальный метод в классе этого объекта. Если он найден, он вызывается для выполнения операции. Если нет, возникает ошибка (обычно TypeError).
Вот пример переопределения оператора сложения (`+`) и оператора вычитания (`-`) в наследуемом классе:
class Vector2D:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"({self.x}, {self.y})"
def __add__(self, other):
"""Переопределение оператора +"""
if isinstance(other, Vector2D):
return Vector2D(self.x + other.x, self.y + other.y)
else:
raise TypeError("Нельзя сложить Vector2D с объектом другого типа")
def __sub__(self, other):
"""Переопределение оператора -"""
if isinstance(other, Vector2D):
return Vector2D(self.x - other.x, self.y - other.y)
else:
raise TypeError("Нельзя вычесть Vector2D из объекта другого типа")
class Vector3D(Vector2D): # Наследуемся от Vector2D
def __init__(self, x, y, z):
super().__init__(x, y)
self.z = z
def __str__(self):
return f"({self.x}, {self.y}, {self.z})"
def __add__(self, other):
"""Переопределение оператора + для Vector3D"""
if isinstance(other, Vector3D):
return Vector3D(self.x + other.x, self.y + other.y, self.z + other.z)
elif isinstance(other, Vector2D): # Допустим сложение с Vector2D
return Vector3D(self.x + other.x, self.y + other.y, self.z) # z остается прежним
else:
return super().__add__(other) # Позволяем родителю вызвать исключение TypeError
def __sub__(self, other):
"""Переопределение оператора - для Vector3D"""
if isinstance(other, Vector3D):
return Vector3D(self.x - other.x, self.y - other.y, self.z - other.z)
elif isinstance(other, Vector2D):
return Vector3D(self.x - other.x, self.y - other.y, self.z)
else:
return super().__sub__(other)
# Пример использования
v1 = Vector2D(1, 2)
v2 = Vector2D(3, 4)
v3 = Vector3D(5, 6, 7)
v4 = Vector3D(1, 1, 1)
print(f"v1 + v2 = {v1 + v2}") # Output: v1 + v2 = (4, 6)
print(f"v3 + v4 = {v3 + v4}") # Output: v3 + v4 = (6, 7, 8)
print(f"v3 + v1 = {v3 + v1}") # Output: v3 + v1 = (6, 8, 7)
print(f"v3 - v1 = {v3 - v1}") # Output: v3 - v1 = (4, 4, 7)
Ключевые моменты:
Перегрузка операторов позволяет сделать код более читаемым и интуитивно понятным, особенно при работе с математическими или другими типами данных, где операторы имеют четкий смысл.