← Назад к вопросам

Какие знаешь магические методы в Python?

2.0 Middle🔥 191 комментариев
#Python

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Магические методы в Python

Магические методы (dunder methods) - это методы с двойными подчёркиваниями, которые позволяют определить поведение объектов при использовании встроенных операций Python. Они критически важны для создания полнофункциональных классов.

1. Инициализация и представление

class Person:
    def __init__(self, name, age):
        """Конструктор - вызывается при создании"""
        self.name = name
        self.age = age
    
    def __str__(self):
        """Строковое представление для пользователя"""
        return f"{self.name} ({self.age} лет)"
    
    def __repr__(self):
        """Официальное представление для разработчика"""
        return f"Person(name='{self.name}', age={self.age})"
    
    def __del__(self):
        """Деструктор - вызывается при удалении"""
        print(f"Удален {self.name}")

p = Person("Alice", 30)
print(str(p))   # __str__
print(repr(p))  # __repr__

2. Методы сравнения

class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price
    
    def __eq__(self, other):
        """Равенство (==)"""
        return self.price == other.price
    
    def __lt__(self, other):
        """Меньше (<)"""
        return self.price < other.price
    
    def __le__(self, other):
        """Меньше или равно (<=)"""
        return self.price <= other.price
    
    def __gt__(self, other):
        """Больше (>)"""
        return self.price > other.price
    
    def __ge__(self, other):
        """Больше или равно (>=)"""
        return self.price >= other.price
    
    def __ne__(self, other):
        """Не равно (!=)"""
        return self.price != other.price

p1 = Product("Laptop", 1000)
p2 = Product("Mouse", 20)
print(p1 > p2)  # True

3. Арифметические операции

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __add__(self, other):
        """Сложение (+)"""
        return Vector(self.x + other.x, self.y + other.y)
    
    def __sub__(self, other):
        """Вычитание (-)"""
        return Vector(self.x - other.x, self.y - other.y)
    
    def __mul__(self, scalar):
        """Умножение (*)"""
        return Vector(self.x * scalar, self.y * scalar)
    
    def __truediv__(self, scalar):
        """Деление (/)"""
        return Vector(self.x / scalar, self.y / scalar)
    
    def __floordiv__(self, scalar):
        """Целочисленное деление (//)"""
        return Vector(self.x // scalar, self.y // scalar)
    
    def __mod__(self, scalar):
        """Остаток (%)"""
        return Vector(self.x % scalar, self.y % scalar)
    
    def __pow__(self, power):
        """Возведение в степень (**)"""
        return Vector(self.x ** power, self.y ** power)
    
    def __repr__(self):
        return f"Vector({self.x}, {self.y})"

v1 = Vector(3, 4)
v2 = Vector(1, 2)
print(v1 + v2)  # Vector(4, 6)
print(v1 * 2)   # Vector(6, 8)

4. Методы контейнеров

class CustomList:
    def __init__(self, items):
        self.items = items
    
    def __len__(self):
        """Длина - len()"""
        return len(self.items)
    
    def __getitem__(self, index):
        """Получение элемента - obj[index]"""
        return self.items[index]
    
    def __setitem__(self, index, value):
        """Установка элемента - obj[index] = value"""
        self.items[index] = value
    
    def __delitem__(self, index):
        """Удаление элемента - del obj[index]"""
        del self.items[index]
    
    def __contains__(self, item):
        """Проверка наличия - item in obj"""
        return item in self.items
    
    def __iter__(self):
        """Итератор - for item in obj"""
        return iter(self.items)
    
    def __reversed__(self):
        """Обратный порядок - reversed(obj)"""
        return reversed(self.items)

cl = CustomList([1, 2, 3, 4, 5])
print(len(cl))      # 5
print(cl[2])        # 3
print(3 in cl)      # True

5. Вызываемые объекты

class Multiplier:
    def __init__(self, factor):
        self.factor = factor
    
    def __call__(self, x):
        """Делает объект вызываемым - obj()"""
        return x * self.factor

times_three = Multiplier(3)
print(times_three(10))  # 30

# Применяем как функцию
result = list(map(times_three, [1, 2, 3, 4, 5]))
print(result)  # [3, 6, 9, 12, 15]

6. Context Manager (with statement)

class DatabaseConnection:
    def __init__(self, connection_string):
        self.connection_string = connection_string
        self.connection = None
    
    def __enter__(self):
        """Вход в контекст"""
        print(f"Подключение к {self.connection_string}")
        self.connection = "connected"
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """Выход из контекста"""
        print("Отключение")
        self.connection = None
        return False

with DatabaseConnection("postgresql://localhost") as db:
    print(f"Статус: {db.connection}")

7. Хеширование и форматирование

class Fraction:
    def __init__(self, numerator, denominator):
        self.numerator = numerator
        self.denominator = denominator
    
    def __hash__(self):
        """Хеш для dict и set"""
        return hash((self.numerator, self.denominator))
    
    def __format__(self, format_spec):
        """Форматирование - f\"{obj:spec}\""""
        return f"{self.numerator}/{self.denominator}"
    
    def __int__(self):
        """Преобразование в int()"""
        return self.numerator // self.denominator
    
    def __float__(self):
        """Преобразование в float()"""
        return self.numerator / self.denominator
    
    def __bool__(self):
        """Преобразование в bool()"""
        return self.numerator != 0

f = Fraction(3, 4)
print(f"{f:>10}")    # Форматирование
print(float(f))      # 0.75
print(int(f))        # 0
print(bool(f))       # True

8. Управление атрибутами

class DynamicAttributes:
    def __init__(self):
        self.data = {}
    
    def __getattr__(self, name):
        """Вызывается если атрибут не найден"""
        if name in self.data:
            return self.data[name]
        raise AttributeError(f"{name} не существует")
    
    def __setattr__(self, name, value):
        """Вызывается при установке атрибута"""
        if name != 'data':
            if not hasattr(self, 'data'):
                super().__setattr__('data', {})
            self.data[name] = value
        else:
            super().__setattr__(name, value)
    
    def __delattr__(self, name):
        """Вызывается при удалении атрибута"""
        if name in self.data:
            del self.data[name]

obj = DynamicAttributes()
obj.x = 10
print(obj.x)  # 10

Применение в Data Science

class DataVector:
    """Вектор для ML операций"""
    def __init__(self, data):
        self.data = data
    
    def __add__(self, other):
        return DataVector([a + b for a, b in zip(self.data, other.data)])
    
    def __mul__(self, scalar):
        return DataVector([x * scalar for x in self.data])
    
    def __len__(self):
        return len(self.data)
    
    def __repr__(self):
        return f"DataVector({self.data})"

v1 = DataVector([1, 2, 3])
v2 = DataVector([4, 5, 6])
v3 = v1 + v2  # Использует __add__
print(v3)     # DataVector([5, 7, 9])

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

Инициализация: init, del Представление: str, repr, format Сравнение: eq, ne, lt, le, gt, ge Арифметика: add, sub, mul, truediv, mod, pow Контейнеры: len, getitem, setitem, delitem, contains, iter Вызовы: call Контекст: enter, exit Атрибуты: getattr, setattr, delattr

Магические методы позволяют создавать объекты, которые ведут себя как встроенные типы Python, что делает код более интуитивным и мощным.

Какие знаешь магические методы в Python? | PrepBro