Что такое магические методы? Чем __str__ отличается от __repr__?
- Какие dunder-методы вы знаете?
- Для чего нужен __repr__?
- Как сделать объект сравнимым или поддерживающим len()?
Магические методы (__имя__) — крючки, через которые объект поддерживает встроенные операции языка.
__repr__— однозначное представление для разработчика,__str__— читаемое для человекаprintиstr()берут__str__, а если его нет —__repr__
А ещё Ещё примеры: __eq__/__hash__, __len__, __iter__, __enter__/__exit__, __call__
Подробно
Python вызывает магические методы сам, когда вы используете встроенный синтаксис: len(x) → x.__len__(), a + b → a.__add__(b), a == b → a.__eq__(b), for → __iter__, with → __enter__/__exit__, obj() → __call__. Реализовав их, свой класс начинает вести себя как встроенный тип.
**__repr__ и __str__.**
__repr__— для отладки и логов: однозначно описывает объект, в идеале так, чтобы по строке можно было его воссоздать:Point(x=1, y=2). Его показывают консоль, отладчик и контейнеры:print([p])выведетreprэлементов.__str__— для пользователя:print(p),str(p), f-строки.- Если
__str__нет, используется__repr__; наоборот — нет. Поэтому писать стоит хотя бы__repr__.
Сравнение и хеш. Переопределив __eq__, нужно позаботиться о __hash__: иначе объект станет нехешируемым. Для упорядочивания хватит __eq__ и __lt__ с декоратором functools.total_ordering.
@dataclass генерирует __init__, __repr__ и __eq__ сам.
Пример
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
def __str__(self):
return f"({self.x}, {self.y})"
def __eq__(self, other):
return isinstance(other, Point) and (self.x, self.y) == (other.x, other.y)
def __hash__(self):
return hash((self.x, self.y))
p = Point(1, 2)
print(p) # (1, 2)
print([p]) # [Point(x=1, y=2)] — у элементов reprЧто хотят услышать
- Что такое магические методы и что их вызывает сам язык.
- Различие назначения
__repr__и__str__, правило подстановки. - Несколько примеров за пределами строкового представления.
- Связь
__eq__и__hash__.
Частые ошибки
- Сказать, что
__str__и__repr__взаимозаменяемы в обе стороны. - Переопределить
__eq__и забыть про__hash__.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✓__repr__ — однозначно для разработчика, __str__ — читаемо для человека; без __str__ берётся __repr__
- ✗print всегда использует __repr__, даже если определён __str__, а без __repr__ Python подставит __str__
- ✗__str__ и __repr__ всегда должны возвращать одно и то же
- ✗Магические методы можно вызывать только напрямую, встроенные операции их не используют
Что спросят дальше
Разбор темы
- ООП в Python — классы, свойства, наследование и dataclass
self и __init__, магические методы, property, staticmethod и classmethod, MRO и super, dataclass против namedtuple и Pydantic, ABC и Protocol, метаклассы.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.