Что такое магические (dunder) методы в Python?

Ответ

Магические (или 'dunder' от 'double underscore') методы в Python — это специальные методы, имена которых начинаются и заканчиваются двойным подчёркиванием (например, __init__, __str__, __add__). Они являются ключевым элементом объектной модели Python и позволяют классам реализовывать определённые протоколы (например, протокол итерации, протокол контейнера) и переопределять поведение встроенных операций и функций.

Назначение и 'почему':

  • Интеграция с Python: Позволяют классам взаимодействовать со встроенными функциями (например, len(), str(), repr()) и операторами (+, -, ==), делая объекты более 'Pythonic' и интуитивно понятными.
  • Перегрузка операторов: Реализуют перегрузку операторов, позволяя определять, как объекты вашего класса будут реагировать на стандартные арифметические, логические или битовые операции.
  • Управление жизненным циклом: Определяют поведение объекта на различных этапах его существования (создание, инициализация, удаление).
  • Протоколы: Позволяют классу соответствовать определённым протоколам (например, протокол последовательности для __getitem__, __len__).

Примеры:

class Vector:
    def __init__(self, x, y):  # Конструктор: инициализация объекта
        self.x = x
        self.y = y

    def __str__(self):  # Строковое представление для пользователя (вызывается print())
        return f"Vector({self.x}, {self.y})"

    def __repr__(self): # Официальное строковое представление для разработчика (отладка, repr())
        return f"Vector(x={self.x}, y={self.y})"

    def __add__(self, other):  # Перегрузка оператора '+': сложение векторов
        if not isinstance(other, Vector):
            raise TypeError("Can only add Vector to Vector")
        return Vector(self.x + other.x, self.y + other.y)

    def __len__(self): # Перегрузка функции len()
        return 2 # Для примера, длина вектора из 2х координат

v1 = Vector(1, 2)
v2 = Vector(3, 4)

print(v1)       # Вызывает __str__: Vector(1, 2)
print(repr(v1)) # Вызывает __repr__: Vector(x=1, y=2)
v3 = v1 + v2
print(v3)       # Вызывает __add__, затем __str__: Vector(4, 6)
print(len(v1))  # Вызывает __len__: 2

Основные категории магических методов:

  • Инициализация и удаление: __init__ (инициализация), __new__ (создание экземпляра), __del__ (удаление).
  • Строковое представление: __str__ (для пользователя), __repr__ (для разработчика).
  • Арифметические операции: __add__, __sub__, __mul__, __truediv__ и т.д.
  • Сравнение: __eq__, __ne__, __lt__, __gt__ и т.д.
  • Контейнерные методы: __len__, __getitem__, __setitem__, __contains__ (для работы с объектом как со списком/словарём).
  • Вызываемые объекты: __call__ (позволяет экземпляру объекта вести себя как функция).