Специальные методы: __repr__, __str__, __eq__, __len__
Содержание курса
В предыдущих уроках мы разбирались с тем, как устроены классы изнутри: атрибуты экземпляра, инкапсуляция, classmethod и staticmethod. Всё это — про то, как объект хранит данные и что с ними делает. Но есть ещё один пласт: как объект себя показывает. Python предоставляет несколько специальных методов, которые управляют представлением объекта в разных контекстах — в консоли, в логах, при сравнении, при подсчёте длины. В этом уроке разберём четыре из них: repr, str, eq и len.
repr и str: назначение и различие
Каждый объект в Python умеет превращаться в строку. Вопрос в том, для кого эта строка предназначена.
__repr__ — это представление для разработчика. Его задача — однозначно идентифицировать объект: показать, что это за тип и какие у него ключевые данные. Когда ты смотришь в отладчик, читаешь лог или просто вводишь объект в интерактивной сессии Python — ты видишь именно то, что возвращает __repr__.
__str__ — это представление для пользователя. Оно может быть более лаконичным, более «читабельным», без технических деталей. Именно его Python показывает при print() и в f-строках.
Если одним словом: __repr__ — для тебя как инженера, __str__ — для того, кто смотрит на вывод программы.
Распространённое заблуждение про __repr__
Многие считают, что __repr__ обязан возвращать строку, которую можно передать в eval() и получить обратно точно такой же объект. То есть что-то вроде:
"MyClass(name='Rock', count=3)"
Это полезная практика — но не обязательное требование. Стандарт Python говорит лишь о том, что строка должна быть информативной и однозначной. Если воспроизвести объект через eval() невозможно или слишком дорого — это нормально.
Чего точно не должен делать __repr__: возвращать пустую строку или строку без смысловой нагрузки. Дефолтный вывод вида <__main__.MyClass object at 0x7f3a2> — это и есть провал отсутствующего __repr__: технически работает, практически бесполезен.
При этом совпадение __repr__ и __str__ — вполне допустимая ситуация. Для простых типов (числовых обёрток, value objects) оба метода часто возвращают одно и то же. Разделять их стоит тогда, когда разным аудиториям нужны разные уровни детализации: например, разработчику важен полный список треков, а пользователю достаточно их количества.
Ключевая разница в одной фразе
__repr__ отвечает на вопрос «что это за объект?», __str__ — на вопрос «как это показать?». Иногда ответы совпадают, иногда нет. Именно поэтому в Python есть оба метода, а не один.
