Когда полезен вывод repr?

Я читал о repr в Python. Мне было интересно, каково применение вывода repr. например

class A:
 pass

repr(A) ='<class __main__.A at 0x6f570>'

b=A()
repr(b) = '<__main__.A instance at 0x74d78>'

Когда можно было бы заинтересоваться '<class __main__.A at 0x6f570>' или '<__main__.A instance at 0x74d78>'?


person shaz    schedule 11.01.2011    source источник


Ответы (3)


Иногда вам приходится иметь дело или представить строку байтов, например

bob2='bob\xf0\xa4\xad\xa2'

Если вы распечатаете это (в Ubuntu), вы получите

In [62]: print(bob2)
bob????

что не очень полезно для других, пытающихся понять вашу байтовую строку. В комментариях Джон указывает, что в Windows print(bob2) приводит к чему-то вроде bob𤭢. Проблема в том, что Python определяет кодировку вашего терминала/консоли по умолчанию и пытается декодировать строку байтов в соответствии с этой кодировкой. Поскольку Ubuntu и Windows используют разные кодировки по умолчанию (возможно, utf-8 и cp1252 соответственно), получаются разные результаты.

Напротив, представление строки однозначно:

In [63]: print(repr(bob2))
'bob\xf0\xa4\xad\xa2'

Когда люди публикуют здесь на SO вопросы о строках Python, их часто просят показать представление строки, чтобы мы точно знали, с какой строкой они имеют дело.

В общем, repr должен быть однозначным строковым представлением объекта. repr(obj) вызывает метод __repr__ объекта obj. Так как в вашем примере класс A не имеет своего метода __repr__, repr(b) прибегает к указанию класса и адреса памяти.

Вы можете переопределить метод __repr__, чтобы предоставить более релевантную информацию.


В вашем примере '<__main__.A instance at 0x74d78>' сообщает нам две полезные вещи:

  1. что b является экземпляром класса A в пространстве имен __main__,
  2. и что объект находится в памяти по адресу 0x74d78.

Например, у вас может быть два экземпляра класса A. Если у них один и тот же адрес памяти, то вы знаете, что они «указывают» на один и тот же базовый объект. (Обратите внимание, что эту информацию можно также получить с помощью id).

person unutbu    schedule 11.01.2011
comment
(0) Пожалуйста, не говорите о байтовых строках, не упоминая предполагаемую/известную кодировку (1) На самом деле, добавляя вес к причине использования repr(), не все получают этот символ CJK, отображаемый при печати этой строки; в IDLE в Windows каждый получает bob𤭢 ... после «bob» должно быть 4 символа, и я вижу 4 в IDLE, но в этом SO-комментарии я вижу только 3; предположительно \xAD рассматривается как мягкий дефис. (2) Полезно для строк Unicode, а не только для байтовых строк. Пример: u'bob\U00024b62' - person John Machin; 11.01.2011

Теоретически repr(obj) должен выдать строку, которую можно передать eval для воссоздания объекта. Другими словами,

obj2 = eval(repr(obj1))

должен воспроизводить объект.

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

person mipadi    schedule 11.01.2011
comment
только что попробовал и получил следующее ››› obj = eval(repr(w)) Traceback (последний последний вызов): Файл ‹stdin›, строка 1, в ‹module› Файл ‹string›, строка 1 ‹__main__ .A экземпляр по адресу 0x74d78› ^ SyntaxError: неверный синтаксис - person shaz; 11.01.2011
comment
@shaz: Что ж? Это должно работать, например, с w = 'a string'. - person nmichaels; 11.01.2011
comment
w является экземпляром класса A, т.е. w = A() - person shaz; 11.01.2011
comment
@shaz: в случае вашего объекта он не выводит строку, которую можно вернуть обратно в eval. (Это было первоначальным намерением repr, но оно в основном игнорировалось.) - person mipadi; 12.01.2011

Основная цель repr() заключается в том, что он используется в интерактивном интерпретаторе и в отладчике для форматирования объектов в удобочитаемой форме. Приведенный вами пример в основном полезен для целей отладки.

person Sven Marnach    schedule 11.01.2011