Ответ
Магические методы, также известные как "dunder" методы (от "double underscore" — двойное подчеркивание), — это специальные методы в Python, имена которых начинаются и заканчиваются двойным подчеркиванием (например, __init__, __str__). Они позволяют классам реализовывать определенные протоколы и переопределять поведение встроенных операций и функций.
Назначение: Dunder методы используются для:
- Операторной перегрузки: Изменение поведения стандартных операторов (например,
+,-,==,[]) для пользовательских объектов. - Реализации протоколов: Позволяют объектам вести себя как контейнеры, итераторы, числовые типы и т.д., интегрируясь с функциями Python (например,
len(),str(),for...in). - Управления жизненным циклом объекта: Инициализация, удаление, создание.
Основные категории и примеры:
-
Инициализация и удаление объектов:
__new__(cls, ...): Вызывается для создания нового экземпляра класса.__init__(self, ...): Конструктор, инициализирует созданный объект.__del__(self): Деструктор, вызывается при удалении объекта (не гарантировано).
-
Строковое представление:
__str__(self): Определяет "официальное" строковое представление объекта, используемое функциейstr()иprint(). Должно быть читабельным для пользователя.__repr__(self): Определяет "неофициальное" строковое представление, используемое функциейrepr()и в интерактивной консоли. Должно быть однозначным и, по возможности, позволять воссоздать объект.
-
Сравнение объектов (операторы сравнения):
__eq__(self, other):self == other__ne__(self, other):self != other__lt__(self, other):self < other__le__(self, other):self <= other__gt__(self, other):self > other__ge__(self, other):self >= other
-
Контейнерные протоколы (доступ к элементам):
__len__(self):len(self)__getitem__(self, key):self[key](доступ по индексу/ключу)__setitem__(self, key, value):self[key] = value__delitem__(self, key):del self[key]__contains__(self, item):item in self
-
Арифметические операции:
__add__(self, other):self + other__sub__(self, other):self - other__mul__(self, other):self * other- И многие другие (
__truediv__,__floordiv__,__mod__,__pow__и т.д.).
Пример использования:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
"""Представление для разработчика."""
return f"Point(x={self.x}, y={self.y})"
def __str__(self):
"""Представление для пользователя."""
return f"({self.x}, {self.y})"
def __add__(self, other):
"""Перегрузка оператора сложения для сложения двух точек."""
if isinstance(other, Point):
return Point(self.x + other.x, self.y + other.y)
raise TypeError("Можно складывать только с объектом Point")
def __eq__(self, other):
"""Перегрузка оператора равенства."""
if isinstance(other, Point):
return self.x == other.x and self.y == other.y
return NotImplemented # Позволяет другому объекту попробовать сравнение
p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = Point(1, 2)
print(p1) # Вызывает __str__: (1, 2)
print(repr(p1)) # Вызывает __repr__: Point(x=1, y=2)
p_sum = p1 + p2
print(f"Сумма точек: {p_sum}") # (4, 6)
print(f"p1 == p2: {p1 == p2}") # False
print(f"p1 == p3: {p1 == p3}") # True