Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tell IPython to use an object's `__str__` instead of `__repr__` for output

Tags:

repr

ipython

By default, when IPython displays an object, it seems to use __repr__.

__repr__ is supposed to produce a unique string which could be used to reconstruct an object, given the right environment. This is distinct from __str__, which supposed to produce human-readable output.

Now suppose we've written a particular class and we'd like IPython to produce human readable output by default (i.e. without explicitly calling print or __str__). We don't want to fudge it by making our class's __repr__ do __str__'s job. That would be breaking the rules.

Is there a way to tell IPython to invoke __str__ by default for a particular class?

like image 272
DanielSank Avatar asked Jan 03 '17 22:01

DanielSank


People also ask

Should I use repr or str?

str() is used for creating output for end user while repr() is mainly used for debugging and development. repr's goal is to be unambiguous and str's is to be readable.

What is the purpose of defining the functions __ str __ and __ repr __ within a class how are the two functions different?

Well, the __str__ function is supposed to return a human-readable format, which is good for logging or to display some information about the object. Whereas, the __repr__ function is supposed to return an “official” string representation of the object, which can be used to construct the object again.

What is the use of __ str __ in Python?

The __str__ method in Python represents the class objects as a string – it can be used for classes. The __str__ method should be defined in a way that is easy to read and outputs all the members of the class. This method is also used as a debugging tool when the members of a class need to be checked.

What is the difference between repr function and str?

In Python, the built-in str() and repr() functions both produce a textual representation of an object. The difference between str() and repr() is: The str() function returns a user-friendly description of an object. The repr() method returns a developer-friendly string representation of an object.


1 Answers

This is certainly possible; you just need implement the instance method _repr_pretty_(self). This is described in the documentation for IPython.lib.pretty. Its implementation could look something like this:

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

The p parameter is an instance of IPython.lib.pretty.PrettyPrinter, whose methods you should use to output the text representation of the object you're formatting. Usually you will use p.text(text) which just adds the given text verbatim to the formatted representation, but you can do things like starting and ending groups if your class represents a collection.

The cycle parameter is a boolean that indicates whether a reference cycle is detected - that is, whether you're trying to format the object twice in the same call stack (which leads to an infinite loop). It may or may not be necessary to consider it depending on what kind of object you're using, but it doesn't hurt.


As a bonus, if you want to do this for a class whose code you don't have access to (or, more accurately, don't want to) modify, or if you just want to make a temporary change for testing, you can use the IPython display formatter's for_type method, as shown in this example of customizing int display. In your case, you would use

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

with MyObject of course representing the type you want to customize the printing of. Note that the lambda function carries the same signature as _repr_pretty_, and works the same way.

like image 128
David Z Avatar answered Oct 26 '22 18:10

David Z