Ответ
__str__ и __repr__ — это методы для получения строкового представления объекта, но они предназначены для разной аудитории и целей.
| Метод | Целевая аудитория | Основная цель | Вызывается функциями | Требования |
|---|---|---|---|---|
__str__(self) |
Конечные пользователи, для удобочитаемого вывода. | Предоставить красивое, неформальное, понятное строковое представление. | print(), str(), f-строки (неявно). |
Читаемость и информативность для человека. |
__repr__(self) |
Разработчики, для отладки и логгирования. | Предоставить однозначное, формальное, максимально полное представление, желательно позволяющее воссоздать объект. | repr(), вывод в интерактивной консоли, логгирование. |
Однозначность. Идеально, если eval(repr(obj)) == obj. |
Простое правило: __repr__ — для разработчика (что это за объект?), __str__ — для пользователя (как это показать?).
Наглядный пример:
class Project:
def __init__(self, name, language, version):
self.name = name
self.language = language
self.version = version
def __str__(self):
# Удобочитаемо для пользователя
return f"Project '{self.name}' (v{self.version})"
def __repr__(self):
# Точное и полное представление для разработчика
# Обратите внимание на экранирование строки name!
return f"Project(name='{self.name}', language='{self.language}', version={self.version})"
# Создаем объект
my_project = Project("Alpha", "Python", 1.5)
print("Using print() / str():")
print(my_project) # Неявно вызывает __str__
print(str(my_project)) # Явный вызов __str__
# Вывод: Project 'Alpha' (v1.5)
print("nUsing repr() or in console:")
print(repr(my_project)) # Явный вызов __repr__
# В интерактивной консоли просто `my_project` выведет это же.
# Вывод: Project(name='Alpha', language='Python', version=1.5)
# Идеальное свойство repr: возможность воссоздания (не всегда достижимо)
try:
# Для простых классов repr может быть исполняемым кодом
copy_project = eval(repr(my_project))
print(f"nCopy created: {copy_project.name}")
except:
pass
Важные детали:
- Fallback: Если метод
__str__не определен, Python использует__repr__в качестве запасного варианта (например, вprint()). Поэтому всегда определяйте__repr__— это хороший тон. - Для коллекций:
print(list)использует__repr__для элементов списка, а не__str__. - Стандартный
__repr__по умолчанию (<__main__.Project object at 0x7f8a1c2b4d90>) бесполезен для отладки. Всегда переопределяйте его.
Правило большого пальца: Сначала напишите информативный __repr__. Затем, если нужен особый формат для вывода пользователю, добавьте __str__.