Ответ
В Python магические методы __str__ и __repr__ определяют строковое представление объекта, но служат разным целям и аудиториям.
-
__repr__(self)— для разработчиков.- Цель: Создать недвусмысленное, официальное представление объекта, которое идеально подходит для отладки.
- Правило хорошего тона: Строка, возвращаемая
__repr__, должна быть таким кодом, который может воссоздать объект. То естьeval(repr(obj)) == obj. - Когда вызывается: Функцией
repr(obj)и при выводе объекта в интерактивной консоли.
-
__str__(self)— для пользователей.- Цель: Создать читаемое, неформальное представление объекта для конечного пользователя.
- Когда вызывается: Функцией
str(obj)и конструкциейprint(obj).
Ключевое правило: Если метод __str__ не реализован, Python автоматически использует __repr__ вместо него. Поэтому рекомендуется всегда реализовывать как минимум __repr__.
Пример
import datetime
class User:
def __init__(self, username, created_at):
self.username = username
self.created_at = created_at
# Представление для отладки: полное и однозначное
def __repr__(self):
return f"User(username='{self.username}', created_at={repr(self.created_at)})"
# Представление для пользователя: краткое и понятное
def __str__(self):
return f"Пользователь: {self.username}"
user = User('admin', datetime.datetime.now())
# Вызов в консоли или repr()
# >> user
# User(username='admin', created_at=datetime.datetime(2023, 10, 27, 10, 30, 0))
print(repr(user))
# Вызов print() или str()
# >> print(user)
# Пользователь: admin
print(str(user)) Ответ 18+ 🔞
А, вот эта тема про __str__ и __repr__! Ну что, дружок-пирожок, давай разберёмся, пока не поехала крыша окончательно.
Представь себе, что у тебя есть объект. Какой-нибудь, блядь, user = User('admin'). И ты его в консольку выводишь. И тут начинается магия, ёпта! А точнее, магические методы.
Вот смотри, есть два этих засранца:
-
__repr__(self)— это, сука, для нас, для разработчиков. Как будто ты наливаешь себе кофе в три часа ночи и пытаешься понять, почему всё сломалось. Его задача — выдать такую строчку, чтобы ты, мудак, сразу понял, что это за объект. Идеально — чтобы эту строчку можно было скопировать, вставить в код, и получился бы такой же объект.eval(repr(obj)) == obj— вот это святое правило, блядь! Вызывается, когда пишешьrepr(obj)или просто смотришь на объект в консоли. -
__str__(self)— это уже для пользователей, для этих, блядь, мирных жителей. Чтобы им красиво и понятно показать: «О, смотрите, это пользователь Вася!». Не надо тут никаких дат создания и внутренних айдишников. Просто «Пользователь: admin». Вызывается, когда делаешьprint(obj)илиstr(obj).
А теперь главный прикол, в рот меня чих-пых! Если ты такой умный и не написал __str__, то Python, хитрая жопа, возьмёт и подставит вместо него __repr__. Поэтому, если реализовывать что-то одно — делай __repr__. Но лучше оба, ёпта.
Смотри, как это выглядит на практике
import datetime
class User:
def __init__(self, username, created_at):
self.username = username
self.created_at = created_at
# Это для отладки, чтобы я, обалдевший, мог всё понять
def __repr__(self):
return f"User(username='{self.username}', created_at={repr(self.created_at)})"
# А это уже для красивого вывода в лог или интерфейс
def __str__(self):
return f"Пользователь: {self.username}"
user = User('admin', datetime.datetime.now())
# Вот это вызовет __repr__ — полная техническая информация, как в черном ящике
# User(username='admin', created_at=datetime.datetime(2023, 10, 27, 10, 30, 0))
print(repr(user))
# А вот это вызовет __str__ — коротко и ясно для всех
# Пользователь: admin
print(str(user))
Вот и вся разница, блядь. Один для дебага, другой — для красоты. Не перепутай, а то пользователям вместо «Привет, Иван» вылезет какая-нибудь User object at 0x7f8b1d2c3d90, и они тебе такого наговорят, мало не покажется.