Разница между __str__ и __repr__? - PullRequest
       167

Разница между __str__ и __repr__?

2417 голосов
/ 17 сентября 2009

В чем разница между __str__ и __repr__ в Python?

Ответы [ 22 ]

10 голосов
/ 17 сентября 2009

С (неофициальная) справочная вики-версия Python (архивная копия) от effbot:

__str__ " вычисляет" неформальное "строковое представление объекта. Это отличается от __repr__ тем, что оно не обязательно должно быть допустимым выражением Python: вместо него можно использовать более удобное или краткое представление ."

7 голосов
/ 26 мая 2017

Один аспект, который отсутствует в других ответах. Это правда, что в целом картина такова:

  • Цель __str__: человекочитаем
  • Цель __repr__: однозначный, возможно, машиночитаемый через eval

К сожалению, это различие некорректно, потому что в Python REPL и IPython используется __repr__ для печати объектов в консоли REPL (см. Связанные вопросы для Python и IPython ). Таким образом, проекты, предназначенные для работы с интерактивной консолью (например, Numpy или Pandas), начали игнорировать вышеприведенные правила и вместо этого предоставляют удобочитаемую __repr__ реализацию.

6 голосов
/ 04 декабря 2016

str - Создает новый строковый объект из данного объекта.

repr - Возвращает каноническое строковое представление объекта.

Различия:

ул ():

  • делает объект читабельным
  • создает вывод для конечного пользователя

магнезии ():

  • нужен код, который воспроизводит объект
  • создает вывод для разработчика
4 голосов
/ 04 апреля 2017

Из книги Свободный Питон :

Основным требованием для объекта Python является предоставление пригодного для использования строковые представления самого себя, один используется для отладки и ведение журнала, еще один для представления конечным пользователям. Вот почему
в модели данных существуют специальные методы __repr__ и __str__.

4 голосов
/ 29 октября 2015

Отличные ответы уже охватывают разницу между __str__ и __repr__, которая для меня сводится к тому, что первое читается даже конечным пользователем, а последнее максимально полезно для разработчиков. Учитывая это, я считаю, что реализация по умолчанию __repr__ часто не позволяет достичь этой цели, потому что она пропускает информацию, полезную для разработчиков.

По этой причине, если у меня достаточно простой __str__, я обычно просто пытаюсь получить лучшее из обоих миров с чем-то вроде:

def __repr__(self):
    return '{0} ({1})'.format(object.__repr__(self), str(self))
3 голосов
/ 23 марта 2018

В двух словах:

class Demo:
  def __repr__(self):
    return 'repr'
  def __str__(self):
    return 'str'

demo = Demo()
print(demo) # use __str__, output 'str' to stdout

s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'

import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout

from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'
3 голосов
/ 15 июля 2015
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')

Когда print() вызывается по результату decimal.Decimal(23) / decimal.Decimal("1.05"), печатается необработанное число; этот вывод находится в строковой форме , что может быть достигнуто с помощью __str__(). Если мы просто введем выражение, мы получим вывод decimal.Decimal - этот вывод будет в представительной форме , что может быть достигнуто с помощью __repr__(). Все объекты Python имеют две выходные формы. Строковая форма разработана для восприятия человеком. Форма представления предназначена для создания выходных данных, которые при передаче интерпретатору Python (когда это возможно) воспроизводят представленный объект.

3 голосов
/ 16 ноября 2015

Важно помнить, что контейнер __str__ использует содержащиеся в нем объекты __repr__.

>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"

Python поддерживает однозначность перед читаемостью , вызов __str__ для tuple вызывает содержащиеся в объектах __repr__, "формальное" представление объекта. Хотя формальное представление труднее читать, чем неформальное, оно однозначно и более устойчиво к ошибкам.

2 голосов
/ 07 декабря 2017

Понять __str__ и __repr__ интуитивно и постоянно различать их.

__str__ вернуть замаскированное тело строки данного объекта для чтения с глаз
__repr__ вернуть реальное тело данного объекта (вернуть себя) для однозначности для идентификации.

см. Пример

In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form

Что касается __repr__

In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.

Мы можем удобно выполнять арифметические операции с результатами __repr__.

In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
    ...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)

, если применить операцию к __str__

In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'

ничего не возвращает, кроме ошибки.

Другой пример.

In [36]: str('string_body')
Out[36]: 'string_body' # in string form

In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside

Надеюсь, это поможет вам заложить конкретные основания, чтобы найти больше ответов.

1 голос
/ 08 мая 2018

__repr__ используется везде, кроме методов print и str (когда определено __str__!)

...