Разница между __str__ и __repr__ в Python
Подробное объяснение разницы между методами __str__ и __repr__ в Python. __str__ для человекочитаемого вывода в print(), __repr__ для отладки и eval(). Примеры, лучшие практики и fallback-механизм.
В чём разница между __str__ и __repr__ в Python?
Метод __str__ в Python предназначен для создания человекочитаемого строкового представления объекта, которое удобно показывать пользователям через print() или str(). В отличие от него, __repr__ возвращает детальное, “кодовое” представление, подходящее для отладки и восстановления объекта через eval(). Разница между __str__ и reprзаключается в аудитории: первое — для конечных пользователей, второе — для разработчиков, и еслиstrне определён, Python fallback'нется наrepr`.
Содержание
- Разница между str и repr в Python
- Что такое метод str в Python
- Что такое метод repr в Python
- Когда и как Python вызывает эти методы
- Практические примеры реализации
- Лучшие практики и распространённые ошибки
- Источники
- Заключение
Разница между str и repr в Python
Разница между __str__ и __repr__ в Python не такая уж сложная, но её понимание спасает кучу времени на отладке. __str__ — это когда вы хотите, чтобы объект выглядел красиво для обычного человека. Запускаете print(obj) — и бац, читаемый текст вроде “Иван, 30 лет”. А __repr__ — штука для кодеров: она должна давать строку, которую можно скопировать и запустить через eval(), чтобы получить точную копию объекта.
Почему это важно? Представьте: вы пишете класс для модели данных. Пользователь видит удобный вывод, а вы в консоли — полную картину с типом и аргументами. Документация на Timeweb чётко объясняет: __str__ для print() и format(), __repr__ для интерпретатора и репрезентации.
Но вот загвоздка. Если не переопределить __str__, Python сам подставит __repr__. Звучит удобно? На деле приводит к путанице — вдруг в логе увидите <__main__.Person object at 0x7f8b1c0> вместо нормального текста. А в REPL (интерактивной оболочке) всегда работает __repr__, даже если __str__ есть.
Коротко: __str__ — неформальное, дружелюбное. __repr__ — формальное, точное. И да, оба возвращают строки, но цели разные.
Что такое метод str в Python
Метод __str__ в Python — ваш билет к читаемому выводу. Он вызывается автоматически при print(my_object), str(my_object) или в f-строках. Цель простая: сделать объект понятным для человека, который не копается в коде.
Возьмём пример. Допустим, класс Person:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"{self.name}, {self.age} лет"
Теперь print(Person("Иван", 30)) выдаст “Иван, 30 лет”. Идеально для логов, UI или отчётов. Real Python подчёркивает: это неформальное представление, как ISO-формат для дат.
Но не переусердствуйте. __str__ не должен быть слишком длинным — пользователи не любят стены текста. И помните, оно не для машин: eval(str(obj)) не сработает.
А что если ничего не определить? Получите дефолтный вывод — скучный и бесполезный.
Что такое метод repr в Python
__repr__ в Python — это инструмент для разработчиков. Он должен возвращать строку, которая выглядит как вызов конструктора, чтобы eval(repr(obj)) воссоздала объект. Идеал: Person('Иван', 30).
Продолжим с нашим классом:
def __repr__(self):
return f"Person('{self.name}', {self.age})"
В REPL просто наберите p = Person("Иван", 30) — увидите Person('Иван', 30). Круто для отладки, pdb или Jupyter. Stack Overflow на русском напоминает: если нет имени типа, это не __repr__.
Почему не всегда идеально? Не все объекты recreatable — функции, генераторы. Тогда делайте максимально информативно: класс, id, ключевые атрибуты.
В отличие от __str__, __repr__ вызывается repr(obj), в интерпретаторе и как fallback для __str__. Pyneng docs приводит пример с IP: __repr__ даёт полный конструктор.
Когда и как Python вызывает эти методы
Python не случайен в выборе. Вот расклад:
print(obj),str(obj)→__str__, если есть, иначе__repr__.repr(obj)→ всегда__repr__.- REPL (>>> obj) →
__repr__. - Форматирование
{obj}→__str__.
Таблица для ясности:
| Функция/Контекст | Метод |
|---|---|
print(obj) |
__str__ (fallback __repr__) |
repr(obj) |
__repr__ |
| Интерпретатор | __repr__ |
format(obj) |
__str__ |
Оригинальный тред на Stack Overflow детализирует: для строк str("hello") → “hello”, repr("hello") → “‘hello’”. Разница видна сразу.
На практике? В pandas DataFrame print(df) использует __str__ для таблицы, но repr(df) — компактный __repr__. Полезно при больших данных.
А если оба метода? Python предпочитает __str__ для print. Логично.
Практические примеры реализации
Давайте кодом. Полный класс:
class IPAddress:
def __init__(self, ip):
self.ip = ip
def __str__(self):
return self.ip # Просто IP для пользователя
def __repr__(self):
return f"IPAddress('{self.ip}')" # Для eval
ip = IPAddress("192.168.1.1")
print(ip) # 192.168.1.1
print(repr(ip)) # IPAddress('192.168.1.1')
eval(repr(ip)) вернёт новый объект. Работает! Timeweb tutorial такой же пример с Person.
Ещё datetime из стандартной библиотеки:
from datetime import datetime
dt = datetime.now()
print(dt) # 2026-01-17 10:30:45.123456 (user-friendly)
repr(dt) # datetime.datetime(2026, 1, 17, 10, 30, 45, 123456) (eval-ready)
Или список: str([1,2]) → “[1, 2]”, repr([1,2]) → “[1, 2]” (почти одинаково, но для вложенных — разница в кавычках).
Что если ошибка? Если __repr__ кидает исключение, увидите <Person object at 0x...>. Лучше ловить ValueError.
На деле эти методы везде: django models, dataclasses (автогенерация).
Лучшие практики и распространённые ошибки
Всегда реализуйте __repr__ первым — он базовый. __str__ — опционально, на его базе. Real Python советует: __repr__ detailed, __str__ concise.
Ошибки новичков:
- Забывают экранировать в
__repr__—evalсломается. - Делают
__str__слишком техничным. - Игнорят immutable объекты — они recreatable легко.
Для dataclasses: @dataclass(repr=True, eq=True) — готово. Но кастомизируйте.
В production? Тестируйте: assert eval(repr(obj)) == obj для __repr__. А __str__ — читайте сами.
Habr sandbox подчёркивает: __str__ для юзеров, __repr__ для devs. Не путайте.
Ещё трюк: наследуйте от abc.ABC для абстрактных, но для простых классов — просто.
Источники
- Как использовать методы str() и repr() в Python
- Чем отличается repr от str? - Stack Overflow (ru)
- What is the difference between str and repr? - Stack Overflow
- Методы str, repr - Python для сетевых инженеров
- When Should You Use .repr() vs .str() in Python? – Real Python
- В чем разница между str и repr в Python / Sandbox / Habr
Заключение
Разница между __str__ и __repr__ в Python проста: первое радует пользователей читаемым выводом, второе помогает разработчикам с отладкой и восстановлением объектов. Реализуйте оба — __repr__ обязательно, __str__ для polish. На практике это сделает ваш код чище, а жизнь проще. Попробуйте в своём проекте прямо сейчас — увидите магию.