2017-01-03 2 views
4

По умолчанию, когда IPython отображает объект, он, похоже, использует __repr__.Сообщите IPython, чтобы использовать объект `__str__` вместо` __repr__` для вывода

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

Теперь предположим, что мы написали конкретный класс, и мы хотели бы, чтобы IPython выдавал удобочитаемый вывод по умолчанию (т. Е. Без явного вызова print или __str__). Мы не хотим выдумывать это, делая работу нашего класса __repr__ do __str__. Это нарушит правила.

Есть ли способ сказать IPython для вызова __str__ по умолчанию для определенного класса?

+0

Связанный: https://stackoverflow.com/questions/28304092/when-i-am-in-the-python-or-ipython-console-what-is-called-when-i-am-returned-an –

+1

«Обычное» решение, насколько мне известно, это просто написать странный «__repr__». Например, кадры данных Pandas делают это. – user2357112

+1

@ пользователь2357112 Awww :-( – DanielSank

ответ

5

Это, безусловно, возможно; вам просто нужно реализовать метод экземпляра _repr_pretty_(self). Это описано в documentation for IPython.lib.pretty. Ее реализация может выглядеть следующим образом:

class MyObject: 
    def _repr_pretty_(self, p, cycle): 
     p.text(str(self) if not cycle else '...') 

Параметр p является экземпляром IPython.lib.pretty.PrettyPrinter, чьи методы следует использовать для вывода текстового представления объекта вы форматирования. Обычно вы будете использовать p.text(text), который просто добавляет заданный text к форматированному представлению, но вы можете делать такие вещи, как начальная и конечная группы, если ваш класс представляет коллекцию.

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


В качестве бонуса, если вы хотите сделать это для класса, код которого вы не имеют доступ (или, точнее, не хотят) изменять, или если вы просто хотите чтобы сделать временное изменение для тестирования, вы можете использовать метод форматирования отображения IPython for_type, как показано в this example of customizing int display. В вашем случае, вы будете использовать

get_ipython().display_formatter.formatters['text/plain'].for_type(
    MyObject, 
    lambda obj, p, cycle: p.text(str(obj) if not cycle else '...') 
) 

с MyObject конечно, представляющий тип, который вы хотите настроить печать. Обратите внимание, что функция лямбда имеет ту же подпись, что и _repr_pretty_, и работает одинаково.

Смежные вопросы