raju
raju

Reputation: 4978

Convention to print an object in python

Is there any standard convention to print an object in python. I know that if I just try to print the object it would print the memory address but I would like to overwrite that method and be able to print human readable format of the object to help in debugging.

is there any standard convention people follow or is it not a good way to define such a method instead there are better alternatives?

Upvotes: 5

Views: 4797

Answers (4)

tobias_k
tobias_k

Reputation: 82899

You can overwrite either the __str__ or the __repr__ method.

There is no convention on how to implement the __str__ method; it can just return any human-readable string representation you want. There is, however, a convention on how to implement the __repr__ method: it should return a string representation of the object so that the object could be recreated from that representation (if possible), i.e. eval(repr(obj)) == obj.

Assuming you have a class Point, __str__ and __repr__ could be implemented like this:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __str__(self):
        return "(%.2f, %.2f)" % (self.x, self.y)
    def __repr__(self):
        return "Point(x=%r, y=%r)" % (self.x, self.y)
    def __eq__(self, other):
        return isinstance(other, Point) and self.x == other.x and self.y == other.y

Example:

>>> p = Point(0.1234, 5.6789)
>>> str(p)
'(0.12, 5.68)'
>>> "The point is %s" % p  # this will call str
'The point is (0.12, 5.68)'
>>> repr(p)
'Point(x=0.1234, y=5.6789)'
>>> p  # echoing p in the interactive shell calls repr internally
Point(x=0.1234, y=5.6789)
>>> eval(repr(p))  # this echos the repr of the new point created by eval
Point(x=0.1234, y=5.6789)
>>> type(eval(repr(p)))
<class '__main__.Point'>
>>> eval(repr(p)) == p
True

Upvotes: 13

alexvassel
alexvassel

Reputation: 10740

The standard way to print custom info about an object (class instance) is to use __str__ method:

class A:
    var = 1

    def __str__(self):
        return 'Accessing from print function, var = {0}'.format(self.var)

In this method you can display any info you want

a = A()
print(a)
>>> Accessing from print function, var = 1

Upvotes: 1

Lennart Regebro
Lennart Regebro

Reputation: 172249

If your object can be represented in a way that allows recreation, then override the __repr__ function. For example, if you can create your object with the following code:

MyObject('foo', 45)

The the __repr__ should return "MyObject('foo', 45)". You then don't need to implement a __str__.

But if the object is so complex that you can't represent it like that, override __str__ instead. You should then return something that both makes it clear the object can't be recreated, and that it is an object. Hence, don't return "foo:45", because that looks like a string, or {'foo': 45} because that looks like a dictionary, and that will confuse you when you debug.

I'd recommend that you keep the brackets, for example <MyObject foo:45>. That way it is clear that you have been printing an object, and it is also clear that it is not just a question of writing MyObject('foo', 45) to recreate the object, but that there is more data stored.

Upvotes: 3

cdarke
cdarke

Reputation: 44354

Implement function __str__ in the class for the object you are printing.

If you are printing objects for a class that you can't alter then it is fairly straightforward to provide your own print function, since you are using Python 3.

Edit: Usually the string returned by __str__ will be specific to the class, but will at least be enough to identify the object. The exact format of the string will vary depending on the class and public attributes.

Edit2: Here is a simple (cutdown) example from a class describing countries:

def __str__(self):
    return "{0:<32} {1:>010}".
        format(self.__name, self.__population)

Upvotes: 5

Related Questions