В Python магические методы (или dunder‑методы – от __ «double underscore») – это специальные функции, которые вызываются автоматически в ответ
на определённые операции над объектами. Они позволяют «настраивать» поведение ваших классов так, будто они встроенные типы языка. В этой статье мы разберём
почти все магические методы, сгруппировав их по назначению, и покажем короткие примеры их использования.
Содержание
- Создание и уничтожение объектов
- Представление и строковое преобразование
- Численные операции
- Контейнерные (коллекционные) методы
- Доступ к атрибутам и их управление
- Контекстные менеджеры
- Вызов объектов как функций
- Итерация и генераторы
- Асинхронные протоколы
- Прочие полезные методы
- Контакты для обращений
Создание и уничтожение объектов
__new__(cls, args, kwargs)– вызывается перед__init__. Создаёт новый экземпляр (обычно переопределяется только в редких случаях,
например, для реализации синглтонов).__init__(self, args, kwargs)– инициализирует уже созданный объект. Здесь обычно назначаются атрибуты.__del__(self)– деструктор. Вызывается, когда объект собирается сборщиком мусора. Не стоит полагаться на него для критических действий.__repr__(self)– «официальное» строковое представление, которое должно быть корректным Python‑выражением, позволяющим воссоздать объект.__str__(self)– «неформальное» представление для печати пользователю.
Пример:
class Point:
def __new__(cls, x, y):
print("Создаём новый объект")
return super.__new__(cls)
def __init__(self, x, y):
print("Инициализируем")
self.x, self.y = x, y
def __repr__(self):
return f"Point({self.x}, {self.y})"
def __str__(self):
return f"({self.x}, {self.y})"
print(repr(p)) # Point(2, 3)
print(str(p)) # (2, 3)
Численные операции
Эти методы позволяют объектам участвовать в арифметических вычислениях, сравнениях и логических операциях.
| Метод | Операция |
|---|---|
__add__(self, other) | self + other |
__radd__(self, other) | обратный вызов, если other не поддерживает + |
__iadd__(self, other) | self += other |
__sub__, __rsub__, __isub__ | вычитание |
__mul__, __rmul__, __imul__ | умножение |
__truediv__, __rtruediv__, __itruediv__ | деление «/» |
__floordiv__, __rfloordiv__, __ifloordiv__ | деление «//» |
__mod__, __rmod__, __imod__ | остаток от деления |
__pow__, __rpow__, __ipow__ | возведение в степень |
__neg__(self) | унарный -self |
__pos__(self) | унарный +self |
__abs__(self) | вызов abs(self) |
__bool__(self) | приведение к логическому bool |
Пример простого вектора:
class Vec:
def __init__(self, x, y):
self.x, self.y = x, y
def __add__(self, other):
return Vec(self.x + other.x, self.y + other.y)
def __repr__(self):
return f"Vec({self.x}, {self.y})"
v1 = Vec(1, 2)
v2 = Vec(3, 4)
print(v1 + v2) # Vec(4, 6)
Контейнерные (коллекционные) методы
Эти dunder‑методы дают возможность вашим объектам вести себя как списки, словари, множества и т.п.
| Метод | Операция |
|---|---|
__len__(self) | len(self) |
__getitem__(self, key) | self[key] |
__setitem__(self, key, value) | self[key] = value |
__delitem__(self, key) | del self[key] |
__iter__(self) | итерация в for |
__contains__(self, item) | оператор in |
__reversed__(self) | обратный итератор |
__bool__(self) | правда/ложь в условных выражениях |
Пример собственного списка:
class MyList:
def __init__(self, *items):
self._data = list(items)
def __len__(self):
return len(self._data)
def __getitem__(self, index):
return self._data[index]
def __setitem__(self, index, value):
self._data[index] = value
def __repr__(self):
return f"MyList({self._data})"
lst = MyList(1, 2, 3)
print(len(lst)) # 3
print(lst[1]) # 2
lst[1] = 20
print(lst) # MyList([1, 20, 3])
Доступ к атрибутам и их управление
Эти методы позволяют перехватывать обращения к свойствам, динамически создавать их, а также контролировать их изменение и удаление.
__getattr__(self, name)– вызывается, когда атрибут не найден обычным способом.__getattribute__(self, name)– вызывается при любом обращении к атрибуту (надёжно использоватьsuper.__getattribute__(name)).__setattr__(self, name, value)– перехват установки атрибута.__delattr__(self, name)– перехват удаления атрибута.__dir__(self)– список атрибутов, используемыйdir.
Пример «ленивой» загрузки свойства:
class LazyConfig:
def __init__(self):
self._cache = {}
def __getattr__(self, name):
# Находим значение только один раз
value = self._load_from_file(name)
self._cache[name] = value
return value
def _load_from_file(self, name):
print(f"Читаем {name} из файла")
return f"value_of_{name}"
cfg = LazyConfig
print(cfg.api_key) # Читаем api_key из файла
print(cfg.api_key) # уже в кэше, вывод без чтения
Контекстные менеджеры
Методы __enter__ и __exit__ позволяют объекту использоваться в конструкции with. Это удобно для работы с файлами, сетевыми соединениями,
транзакциями и т.п.
class ManagedFile:
def __init__(self, path, mode):
self;path = path
self.mode = mode
def __enter__(self):
self.file = open(self.path, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close
# Возврат False – пробрасывать исключения дальше
return False
with ManagedFile('data.txt', 'w') as f:
f.write('Hello, world!')
Вызов объектов как функций
Метод __call__(self, args, *kwargs) делает экземпляр вызываемым, как обычную функцию.
class Counter:
def __init__(self):
self.n = 0
def __call__(self):
self.n += 1
return self.n
c = Counter
print(c) # 1
print(c) # 2
Итерация и генераторы
Для поддержки протокола итерации нужны два метода:
__iter__(self)– возвращает итератор (объект с__next__).__next__(self)– выдаёт следующий элемент или бросаетStopIteration.
Пример собственного генератора:
class CountDown:
def __init__(self, start):
self.current = start
def __iter__(self):
return self
def __next__(self):
if self.current < 0:
raise StopIteration
value = self.current
self.current -= 1
return value
for i in CountDown(5):
print(i)
Асинхронные протоколы
С появлением async/await в Python появились новые магические методы, позволяющие объекту вести себя как корутина или асинхронный итератор.
| Метод | Назначение |
|---|---|
__await__(self) | объект может быть использован в await |
__aiter__(self) | асинхронный итератор – используется в async for |
__anext__(self) | следующий элемент в асинхронном итераторе |
__aenter__(self) | асинхронный контекстный менеджер – async with |
__aexit__(self, exc_type, exc, tb) | завершение асинхронного контекстного менеджера |
Прочие полезные методы
__hash__(self)– делает объект хешируемым (поддержка словарей, множеств).__eq__, __ne__, __lt__, __le__, __gt__, __ge__– сравнение.__copy__(self)и__deepcopy__(self, memo)– поддержка модуляcopy.__slots__– ограничивает набор атрибутов, повышает экономию памяти.__classcell__– используется в реализации вложенных классов.
Контакты для обращений
Если у вас возникли вопросы по магическим методам, нужны консультации или хотите обсудить магию кода – свяжитесь со мной любым удобным способом.
- Телефон: +7 (916) -23‑45‑67 – звонок круглосуточно, без предоплаты, гарантия результата.
- WhatsApp: +7 -16 123‑45‑67 – быстрый чат, бесплатно и без регистрации.
- Telegram: @magic_python – задайте вопрос, получайте ответы в режиме онлайн.
- ВКонтакте: vk.com/magic_python – отзывы клиентов, лучшие практики, поиск мантр и афирмаций для кода.
- Личный приём (офлайн): г. Москва, ул. Пушкинская, д. 10, офис 5 – помогает в решении сложных задач, без предоплаты.
- Онлайн‑консультация (Zoom/Skype): запись без регистрации, доступ 24/7, прямая связь с экспертом.
- Сайт: https://magicmethods.ru – бесплатные уроки, руны кода, мантры для продуктивности.
- Электронная почта: info@magicmethods.ru – пишите, получайте подробные пошаговые инструкции.
Все обращения не берут деньги до полного подтверждения результата. При необходимости – гарантируем возврат в случае, если задача не решена.
Отзывы реальных клиентов можно посмотреть на странице Отзывы. Мы ценим ваше время и всегда готовы задать вопрос и получить полный ответ в любое время.
Надеемся, что данная статья помогла вам разобраться во всех магических методах Python. Используйте их с умом – и ваш код превратится в истинную магическую машину, способную выполнять любые задачи с лёгкостью.