При форматировании строк доступны 3 флага преобразования объекта в строку: !r, !s и !a.
>>> x = "дом" >>> f'{x}' 'дом' >>> f'{x!r}' "'дом'" >>> f'{x!s}' 'дом' >>> f'{x!a}' "'\\u0434\\u043e\\u043c'"
Для фанатов format:
>>> '{0!r}'.format(x) "'дом'" >>> '{!r}'.format(x) "'дом'"
Флаг !r вызывает repr(x), а флаг !s вызывает str(x). Флаг !a вызывает ascii(repr(x)). Функция ascii превращает все символы за пределами набора ASCII (включая русские буквы в юникоде) в их коды. Если флаг не указан, то по умолчанию считается, что он !s.
Для классов __repr__ и __str__ могут иметь различное определение:
class Foo: def __repr__(self): return "репр" def __str__(self): return "строка" x = Foo() print(f'{x!r}') # репр print(f'{x!s}') # строка
Если __str__ нет, то будет вызван __repr__.
Рекомендации: __str__ должен давать нам человеко-читаемое описание объекта, а __repr__ – уникальное представление объекта, по которому можно частично или полностью восстановить состояние этого объекта или хотя бы помочь с отладкой. __str__ – для пользователей, __repr__ — для питонистов.
📎 Отличный пример для наглядности – datetime:
>>> import datetime >>> dt = datetime.datetime(2019, 7, 27) >>> repr(dt) 'datetime.datetime(2019, 7, 27, 0, 0)' >>> str(dt) '2019-07-27 00:00:00' >>> eval(repr(dt)) == dt True
str от datetime просто покажет нам дату и время в удобном формате; repr от datetime вернет строку, в которой будет вызов описан конструктора конкретно этого объекта, да так, что при исполнении этой строки как кода на Python функцией eval – мы получим объект datetime для той же даты. Впрочем, никто нас не обязывает делать этот трюк для каждого объекта.
🐉 Специально для канала @pyway. Подписывайтесь на мой канал в Телеграм @pyway 👈