22 Вопрос: Разница между __str__ и __repr__?

вопрос создан в Wed, May 29, 2019 12:00 AM

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

    
2412
22 ответа                              22                         

Алекс резюмировал хорошо, но, на удивление, был слишком лаконичен.

Прежде всего позвольте мне повторить основные моменты в посте Алекса :

  • Реализация по умолчанию бесполезна (трудно придумать, чего бы не было, но да)
  • __repr__ цель - быть недвусмысленным
  • __str__ цель - быть читабельным
  • Контейнер __str__ использует содержащиеся объекты ’__repr__

Реализация по умолчанию бесполезна

Это в основном сюрприз, потому что настройки Python по умолчанию довольно полезны. Однако в этом случае по умолчанию используется значение __repr__, которое будет действовать следующим образом:

return "%s(%r)" % (self.__class__, self.__dict__)

было бы слишком опасно (например, слишком легко попасть в бесконечную рекурсию, если объекты ссылаются друг на друга). Так что Python справляется. Обратите внимание, что есть одно значение по умолчанию, которое является истинным: если __repr__ определено, а __str__ - нет, объект будет вести себя так, как если бы он был __str__=__repr__.

Это означает, что в простых терминах: почти каждый реализуемый объект должен иметь функционал __repr__, который можно использовать для понимания объекта. Реализация __str__ является необязательной: сделайте это, если вам нужна функциональность «симпатичная печать» (например, используемая генератором отчетов).

Цель __repr__ - быть недвусмысленным

Позвольте мне выйти и сказать это - я не верю в отладчики. Я действительно не знаю, как использовать любой отладчик, и никогда не использовал его серьезно. Кроме того, я считаю, что большая ошибка отладчиков заключается в их основной природе - большинство ошибок, которые я отлаживал, произошли очень давно, в галактике очень далеко. Это означает, что я с религиозным рвением верю в заготовку леса. Ведение журналов - жизненная основа любой достойной серверной системы, работающей по принципу «забей и забудь» Python облегчает вход в систему: возможно, с некоторыми обертками, специфичными для проекта, все, что вам нужно, это

log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)

Но вы должны сделать последний шаг - убедитесь, что у каждого объекта, который вы реализуете, есть полезное повторение, чтобы подобный код мог просто работать. Вот почему возникает вопрос «eval»: если у вас достаточно информации, например, eval(repr(c))==c, это означает, что вы знаете все, что нужно знать о c. Если это достаточно просто, по крайней мере, нечетко, сделайте это. Если нет, убедитесь, что у вас достаточно информации о c в любом случае. Я обычно использую eval-подобный формат: "MyClass(this=%r,that=%r)" % (self.this,self.that). Это не означает, что вы действительно можете создать MyClass или что это правильные аргументы конструктора - но это полезная форма для выражения «это все, что вам нужно знать об этом экземпляре ».

Примечание. Я использовал %r выше, а не %s. Вы всегда хотите использовать символ форматирования repr() [или %r, что эквивалентно] внутри реализации __repr__, или вы наносите поражение цели. Вы хотите иметь возможность различать MyClass(3) и MyClass("3").

Цель __str__ - сделать ее читабельной

В частности, он не предназначен для того, чтобы быть однозначным - обратите внимание, что str(3)==str("3"). Аналогичным образом, если вы реализуете абстракцию IP, ее строка выглядит так, как будто 192.168.1.1 - это нормально. При реализации абстракции даты /времени str может быть «2010/4/12 15:35:22» и т. Д. Цель состоит в том, чтобы представить ее так, чтобы ее захотел прочитать пользователь, а не программист. Отрежьте ненужные цифры, притворитесь каким-то другим классом - если он поддерживает удобочитаемость, это улучшение.

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

Это кажется удивительным, не так ли? Это немного, но насколько бы читабельным было бы

[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]

быть? Не очень. В частности, строки в контейнере слишком легко нарушить его представление строки. Помните, что перед лицом двусмысленности Python сопротивляется искушению угадать. Если вы хотите использовать описанное выше поведение при печати списка, просто

print "[" + ", ".join(l) + "]"

(вы также можете выяснить, что делать со словарями.

Резюме

Реализуйте __repr__ для любого реализуемого вами класса. Это должно быть вторая натура. Реализуйте __str__, если считаете, что было бы полезно иметь строковую версию с ошибками для удобства чтения.

    
2472
2019-02-20 18: 19: 50Z
  1. Определенно не согласен с вашим мнением о том, что отладка - это не выход. Для разработки используйте отладчик (и /или ведение журнала), для производства используйте ведение журнала. С помощью отладчика вы видите все, что пошло не так, когда возникла проблема. Вы можете увидеть полную картину. Если вы не регистрируетесь ВСЕ, вы не можете получить это. Кроме того, если вы регистрируете все, что вам нужно, вам придется просмотреть тонны данных, чтобы получить то, что вы хотите.
    2015-02-21 19: 06: 51Z
  2. Отличный ответ (за исключением части о том, что не используются отладчики). Я просто хотел бы добавить ссылку на этот другой раздел вопросов и ответов о str vs Юникод в Python 3 , что может иметь отношение к обсуждению для людей, которые внесли свой вклад.
    2015-03-23 ​​21: 04: 49Z
  3. ", ".join(l) - использует неправильную практику использования строчной буквы "L" в качестве имени переменной. Давайте не будем учить новичков программированию на таких примерах из авторитетных источников.
    2017-02-16 13: 30: 27Z
  4. plus1 для отладчиков бесполезны и не масштабируются ни на что. Вместо этого увеличьте пропускную способность логирования. И да, это был хорошо написанный пост. Оказывается, __repr__ было то, что мне нужно для отладки. Спасибо за вашу помощь.
    2017-09-29 15: 43: 29Z
  5. ваш отладчик безрассуден, я узнал% r, и это все равно стоит голоса
    2018-12-13 09: 21: 24Z

Мое эмпирическое правило: __repr__ для разработчиков, __str__ для клиентов.

    
451
2009-09-17 11: 35: 13Z
  1. Это верно, потому что для obj = uuid.uuid1 () obj .__ str __ () имеет значение "2d7fc7f0-7706-11e9-94ae-0242ac110002" и obj .__ repr __ ( ) - это «UUID ('2d7fc7f0-7706-11e9-94ae-0242ac110002')». Разработчикам нужна (ценность + происхождение), тогда как клиентам нужна ценность, и им все равно, как они ее получили!
    2019-05-15 11: 45: 02Z

Если вы не предпримете конкретных действий, чтобы гарантировать обратное, большинство классов не имеют полезных результатов ни для одного из них:

>>> class Sic(object): pass
... 
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>> 

Как видите - нет разницы и нет информации, кроме класса и объекта id. Если вы переопределяете только один из двух ...:

>>> class Sic(object): 
...   def __repr__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
foo
>>> class Sic(object):
...   def __str__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
<__main__.Sic object at 0x2617f0>
>>> 

Как вы видите, если вы переопределите __repr__, то это ТАКЖЕ используется для __str__, но не наоборот.

Другие важные сведения, которые необходимо знать: __str__ для встроенного контейнера использует __repr__, а НЕ __str__ для содержащихся в нем элементов. И, несмотря на слова на эту тему, встречающиеся в типичных документах, вряд ли кто-то утруждает себя превращением объектов __repr__ в строку, которую eval может использовать для создания равного объекта (это слишком сложно, и не зная, как на самом деле был импортирован соответствующий модуль, это на самом деле извергнуть невозможно).

Итак, мой совет: сосредоточьтесь на том, чтобы __str__ был достаточно читабельным, а __repr__ - настолько недвусмысленным, насколько это возможно, даже если это мешает нечеткой недостижимой цели создания __repr__.возвращаемое значение приемлемо в качестве ввода для __eval__!

    
363
2009-09-17 04: 49: 40Z
  1. В моих модульных тестах я всегда проверяю, что eval(repr(foo)) оценивает объект, равный foo. Вы правы, что он не будет работать вне моих тестовых случаев, так как я не Не знаю, как импортируется модуль, но это по крайней мере гарантирует, что он работает в некотором предсказуемом контексте. Я думаю, что это хороший способ оценки, если результат __repr__ достаточно явный. Выполнение этого в модульном тесте также помогает гарантировать, что __repr__ соответствует изменениям в классе.
    2011-11-15 19: 58: 01Z
  2. Я всегда стараюсь убедиться, что либо eval(repr(spam)) == spam (по крайней мере, в правильном контексте), либо eval(repr(spam)) поднимает SyntaxError62. Таким образом, вы избегаете путаницы. (И это почти верно для встроенных функций и большей части stdlib, за исключением, например, рекурсивных списков, где a=[]; a.append(a); print(eval(repr(a))) дает вам [[Ellipses]]…) Конечно, я не делаю это для фактического использования eval(repr(spam)), за исключением проверки работоспособности в модульных тестах ... но я делаю иногда копирую и вставляю repr(spam) в интерактивный сеанс.
    2014-09-20 05: 34: 28Z
  3. Почему бы контейнерам (спискам, кортежам) не использовать __str__ для каждого элемента вместо __repr__? Мне кажется, что это неправильно, поскольку я реализовал читаемый __str__ в своем объекте, и когда он является частью списка, я вижу вместо этого более уродливый __repr__.
    2018-01-26 14: 15: 26Z
  4. Просто натолкнулся на досадную ошибку, связанную с тем, что eval(repr(x)) завершается ошибкой даже для встроенных типов: class A(str, Enum): X = 'x' вызовет SyntaxError в eval(repr(A.X))62. Это печально, но понятно. Кстати, eval(str(A.X)) на самом деле работает, но, конечно, только если class A находится в области видимости - так что это, вероятно, не очень полезно.
    2019-01-13 13: 26: 54Z

__repr__ : представление объекта python, обычно eval, преобразует его обратно в этот объект

__str__ : это то, что вы считаете этим объектом в текстовой форме

например.

>>> s="""w'o"w"""
>>> repr(s)
'\'w\\\'o"w\''
>>> str(s)
'w\'o"w'
>>> eval(str(s))==s
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    w'o"w
       ^
SyntaxError: EOL while scanning single-quoted string
>>> eval(repr(s))==s
True
    
155
2012-08-15 19: 40: 17Z
  

Короче говоря, цель __repr__ - быть однозначным, а __str__ - быть   читаемым.

Вот хороший пример:

>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2012-03-14 09:21:58.130922'
>>> repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'

Прочитайте эту документацию для repr:

  

repr(object) р>      

Возвращает строку, содержащую печатаемое представление объекта. Это то же самое значение, полученное в результате преобразований (обратный   цитаты). Иногда полезно иметь доступ к этой операции как   обычная функция. Для многих типов эта функция делает попытку   вернуть строку, которая выдаст объект с тем же значением, когда   передается eval(), в противном случае представление представляет собой строку, заключенную в   угловые скобки, содержащие название типа объекта   вместе с дополнительной информацией, часто включая имя и   адрес объекта. Класс может контролировать то, что возвращает эта функция   для его экземпляров путем определения метода __repr__().

Вот документация для str:

  

str(object='') р>      

Возвращает строку, содержащую красиво напечатанную   представление объекта. Для строк это возвращает строку   сам. Разница с repr(object) заключается в том, что str(object) не   всегда пытайтесь вернуть строку, которая приемлема для eval(); его   цель состоит в том, чтобы вернуть печатную строку. Если нет аргументов, яс учетом, возвращает   пустая строка, ''.

    
134
2013-10-28 00: 23: 46Z
  1. Что здесь означает строка для печати? Можете ли вы объяснить это, пожалуйста?
    2018-08-19 05: 44: 53Z
  

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

__str__ (читается как «строка dunder (двойное подчеркивание)») и __repr__ (читается как «dunder-repper» (для «представление»)) оба являются специальными методами, которые возвращают строки на основе состояния объекта.

__repr__ обеспечивает резервное копирование, если отсутствует __str__.

Итак, сначала нужно написать __repr__, который позволяет вам восстановить экземпляр эквивалентного объекта из строки, которую он возвращает, например. используя eval или введя его символ за символом в оболочке Python.

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

__str__

Если вы напечатаете объект или передадите его format, str.format или str, то если определен метод __str__, будет вызван этот метод, в противном случае будет использоваться __repr__.

__repr__

Метод __repr__ вызывается встроенной функцией repr и является тем, что отображается в вашей оболочке python, когда он вычисляет выражение, возвращающее объект.

Поскольку он предоставляет резервную копию для __str__, если вы можете написать только одну, начните с __repr__

Вот встроенная справка по repr:

repr(...)
    repr(object) -> string

    Return the canonical string representation of the object.
    For most object types, eval(repr(object)) == object.

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

Реализация по умолчанию __repr__

Объект по умолчанию __repr__ - это ( C источник Python ) что-то вроде:

def __repr__(self):
    return '<{0}.{1} object at {2}>'.format(
      self.__module__, type(self).__name__, hex(id(self)))

Это означает, что по умолчанию вы будете печатать модуль, из которого объект, имя класса и шестнадцатеричное представление его расположения в памяти - например:

<__main__.Foo object at 0x7f80665abdd0>

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

Чем может быть полезен __repr__?

Давайте посмотрим, насколько это может быть полезно с помощью оболочки Python и объектов datetime. Сначала нам нужно импортировать модуль datetime:

import datetime

Если мы вызовем datetime.now в оболочке, мы увидим все, что нам нужно для воссоздания эквивалентного объекта datetime. Это создается датой-временем __repr__:

>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)

Если мы печатаем объект datetime, мы видим хороший читабельный (на самом деле, ISO) формат. Это реализуется датой и временем __str__:

>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951

Очень просто восстановить объект, который мы потеряли, потому что мы не присвоили его переменной, скопировав и вставив из вывода __repr__, а затем распечатав его, и мы получим его в том же читаемом человеком виде, что и другой объект:

>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180

Как их реализовать?

В процессе разработки вы захотите воспроизводить объекты в том же состоянии, если это возможно. Так, например, объект datetime определяет __repr__ ( Исходный код Python ). Это довольно сложно из-за всех атрибутов, необходимых для воспроизведения такого объекта:

def __repr__(self):
    """Convert to formal string, for repr()."""
    L = [self._year, self._month, self._day,  # These are never zero
         self._hour, self._minute, self._second, self._microsecond]
    if L[-1] == 0:
        del L[-1]
    if L[-1] == 0:
        del L[-1]
    s = "%s.%s(%s)" % (self.__class__.__module__,
                       self.__class__.__qualname__,
                       ", ".join(map(str, L)))
    if self._tzinfo is not None:
        assert s[-1:] == ")"
        s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
    if self._fold:
        assert s[-1:] == ")"
        s = s[:-1] + ", fold=1)"
    return s

Если вы хотите, чтобы ваш объект имел более удобочитаемое представление, вы можете реализовать __str__ далее. Вот как работает объект datetime ( источник Python ) реализоватьents __str__, что он легко делает, потому что у него уже есть функция для отображения в формате ISO:

def __str__(self):
    "Convert to string, for str()."
    return self.isoformat(sep=' ')

Установите __repr__ = __str__?

Это критика другого ответа, который предлагает установить __repr__ = __str__.

Установка __repr__ = __str__ глупа - __repr__ является запасным вариантом для __str__, а __repr__, написанное для использования разработчиками в отладке, должно быть написано до того, как вы напишите __str__.

__str__ нужен вам только тогда, когда вам нужно текстовое представление объекта.

Заключение

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

    
97
2019-06-02 11: 35: 40Z
  1. Разве это не должно быть что-то вроде type(obj).__qualname__?
    2018-12-01 01: 10: 23Z
  2. @ SolomonUcko да в Python 3, это может показаться так - я искал исходный код, где это реализовано, и я обновлю свой ответ с этой информацией, когда я соберу ее.
    2018-12-01 20: 50: 02Z
  3. Тщательный ответ, как всегда, спасибо @AaronHall.
    2019-06-02 12: 23: 06Z

Помимо всех приведенных ответов, я хотел бы добавить несколько моментов: -

1) __repr__() вызывается, когда вы просто пишете имя объекта на интерактивной консоли python и нажимаете ввод.

2) __str__() вызывается при использовании объекта с оператором печати. ​​

3) Если __str__ отсутствует, то print и любая функция, использующая str(), вызывает __repr__() объекта.

4) __str__() контейнеров, при вызове выполняется метод __repr__() его содержащихся элементов.

5) str(), вызванный в __str__(), потенциально может рекурсировать без базового случая и ошибки на максимальной глубине рекурсии.

6) __repr__() может вызвать repr(), который попытается автоматически избежать бесконечной рекурсии, заменив уже представленный объект на ....

    
25
2018-06-05 07: 47: 41Z

На странице 358 книги Ханса Петтера Лангтангена Сценарии Python для вычислительной науки четко говорится, что

  • __repr__ направлен на полное строковое представление объекта;
  • __str__ должен вернуть хорошую строку для печати. ​​

Итак, я предпочитаю понимать их как

  • repr = размножаться
  • str = строка (представление)

с точки зрения пользователя хотя это недоразумение я сделал при изучении Python.

Небольшой, но хороший пример также приводится на той же странице следующим образом:

Пример

In [38]: str('s')
Out[38]: 's'

In [39]: repr('s')
Out[39]: "'s'"

In [40]: eval(str('s'))
Traceback (most recent call last):

  File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
    eval(str('s'))

  File "<string>", line 1, in <module>

NameError: name 's' is not defined


In [41]: eval(repr('s'))
Out[41]: 's'
    
17
2019-06-19 07: 47: 15Z
  1. Это на стр. # 351.
    2018-12-21 13: 10: 15Z
  2. Это вводит в заблуждение, ссылаясь на repr как воспроизводить. Лучше думать об этом как о представлении.
    2019-06-19 07: 48: 04Z

Честно говоря, eval(repr(obj)) никогда не используется. Если вы обнаружите, что используете его, вам следует остановиться, потому что eval опасен, а строки - очень неэффективный способ сериализации ваших объектов (вместо этого используйте pickle).

Поэтому я бы рекомендовал установить __repr__ = __str__. Причина в том, что str(list) вызывает repr для элементов (я считаю, что это один из самых больших недостатков Python в дизайне, который не был учтен в Python 3). Фактический repr, вероятно, будет не очень полезен, поскольку вывод print [your, objects].

Для этого, по моему опыту, наиболее полезным вариантом использования функции repr является помещение строки внутри другой строки (с использованием форматирования строки). Таким образом, вам не нужно беспокоиться о том, чтобы избежать кавычек или чего-то еще. Но обратите внимание, что здесь не происходит eval.

    
12
2015-04-14 00: 30: 54Z
  1. Я думаю, что это упущено. Использование eval(repr(obj)) является проверкой работоспособности и практическим правилом - если это правильно воссоздает исходный объект, то у вас есть достойная реализация __repr__. Не предполагается, что вы действительно сериализуете объекты таким образом.
    2014-06-06 13: 56: 58Z
  2. eval по своей сути не опасен. Не опаснее unlink, open или записи в файлы. Должны ли мы прекратить запись в файлы, потому что, возможно, злонамеренная атака может использовать произвольный путь к файлу для помещения содержимого внутрь? Все опасно, если тупо используется немыми людьми. Идиотизм опасен. Эффекты Даннинг-Крюгера опасны. eval - это просто функция.
    2016-03-01 15: 12: 18Z

Проще говоря:

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

__repr__ используется для показа строкового представления объекта .

Допустим, я хочу создать класс Fraction, в котором строковое представление дроби равно «(1/2)», а объект (класс дроби) должен быть представлен как «дробь (1,2)»

Итак, мы можем создать простой класс Fraction:

class Fraction:
    def __init__(self, num, den):
        self.__num = num
        self.__den = den

    def __str__(self):
        return '(' + str(self.__num) + '/' + str(self.__den) + ')'

    def __repr__(self):
        return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'



f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)
    
11
2016-07-28 04: 08: 32Z

Из (неофициальной) справочной вики-страницы вики (архивная копия) от effbot:

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

    
10
2019-05-29 12: 51: 25Z
  1. __repr__ никоим образом не требуется для возврата пустого выражения Python.
    2017-10-20 03: 23: 48Z

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

  • Цель __str__: человекочитаемость
  • Цель __repr__: однозначная, возможно, машиночитаемая с помощью eval

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

    
7
2017-05-26 12: 33: 51Z

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

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

Различия:

ул (): сильный> р>

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

магнезии (): сильный> р>

  • нужен код, который воспроизводит объект
  • создает вывод для разработчика
6
2016-12-04 16: 18: 48Z

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

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

def __repr__(self):
    return '{0} ({1})'.format(object.__repr__(self), str(self))
    
4
2018-04-25 19: 35: 20Z

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

  

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

    
4
2019-05-29 12: 57: 22Z
  

Важно помнить, что контейнер __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__, "формальное" представление объекта. Хотя формальное представление труднее читать, чем неформальное, оно однозначно и более устойчиво к ошибкам.

    
3
2015-11-16 03: 02: 21Z
  1. Он использует __repr__, когда он (__str__) не определен! Итак, вы не правы.
    2018-12-21 13: 48: 22Z

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

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
2018-04-16 09: 28: 38Z
>>> 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") печатается необработанный номер; этот вывод находится в строковой форме , котораяn достигается с помощью __str__(). Если мы просто введем выражение, мы получим вывод decimal.Decimal - этот вывод находится в репрезентативной форме , что может быть достигнуто с помощью __repr__(). Все объекты Python имеют две выходные формы. Строковая форма разработана для восприятия человеком. Форма представления предназначена для получения выходных данных, которые при передаче интерпретатору Python (когда это возможно) воспроизводят представленный объект.

    
3
2019-05-29 12: 58: 50Z

Поймите, __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

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

    
2
2018-01-02 10: 36: 32Z

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

    
1
2019-04-14 07: 50: 40Z
  1. __str__ должен возвращать строковый объект, тогда как __repr__ может возвращать любое выражение Python.
  2. Если реализация __str__ отсутствует, функция __repr__ используется в качестве запасного варианта. Если функция реализации __repr__ отсутствует, отступления не будет.
  3. Если функция __repr__ возвращает строковое представление объекта, мы можем пропустить реализацию функции __str__.

Источник: https://www.journaldev.com/22460/python -str-Repr-функции р>     

0
2019-04-18 11: 20: 28Z

__str__ может быть вызван для объекта путем вызова str(obj) и должен вернуть читаемую человеком строку.

__repr__ может быть вызван для объекта путем вызова repr(obj) и должен вернуть внутренний объект (поля /атрибуты объекта)

Этот пример может помочь:

class C1:pass

class C2:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")

class C3:        
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")

class C4:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")


ci1 = C1()    
ci2 = C2()  
ci3 = C3()  
ci4 = C4()

print(ci1)       #<__main__.C1 object at 0x0000024C44A80C18>
print(str(ci1))  #<__main__.C1 object at 0x0000024C44A80C18>
print(repr(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(ci2)       #C2 class str
print(str(ci2))  #C2 class str
print(repr(ci2)) #<__main__.C2 object at 0x0000024C44AE12E8>
print(ci3)       #C3 class repr
print(str(ci3))  #C3 class repr
print(repr(ci3)) #C3 class repr
print(ci4)       #C4 class str 
print(str(ci4))  #C4 class str 
print(repr(ci4)) #C4 class repr
    
0
2019-06-06 16: 53: 43Z
источник размещен Вот