views:

1309

answers:

2

I am learning the ropes in Python. When I try to print an object of class Foobar using the print() function, I get an output like this:

<__main__.Foobar instance at 0x7ff2a18c>

Is there a way I can set the printing behaviour (or the string representation) of a class and its objects? For instance, when I call print() on a class object, I would like to print its data members in a certain format. How to achieve this in Python?

If you are familiar with C++ classes, the above can be achieved for the standard ostream by adding a friend ostream& operator << (ostream&, const Foobar&) method for the class.

+12  A: 
>>> class Test:
...     def __repr__(self):
...         return "Test()"
...     def __str__(self):
...         return "member of Test"
... 
>>> t = Test()
>>> t
Test()
>>> print t
member of Test

The __str__ method is what happens when you print it, and the __repr__ method is what happens when you use the repr() function (or when you look at it with the interactive prompt). If this isn't the most Pythonic method, I apologize, because I'm still learning too - but it works.

If no __str__ method is given, Python will print the result of __repr__ instead. If you define __str__ but not __repr__, Python will use what you see above as the __repr__, but still use __str__ for printing.

Chris Lutz
there's also a __unicode__ method, which you can use instead of __Str__ ; note that it should return a unicode object, not a string (but if you return a string, the conversion to unicode will be done anyway...)
kender
@kender - I didn't know about it, but in retrospect it makes perfect sense given Python 2.x's broken Unicode handling.
Chris Lutz
+4  A: 

As Chris Lutz mentioned, this is defined by the __repr__ method in your class.

From the documentation of repr():

For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a repr() method.

Given the following class Test:

class Test:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __repr__(self):
        return "<Test a:%s b:%s>" % (self.a, self.b)

    def __str__(self):
        return "From str method of Test: a is %s, b is %s" % (self.a, self.b)

..it will act the following way in the Python shell:

>>> t = Test(123, 456)
>>> t
<Test a:123 b:456>
>>> print repr(t)
<Test a:123 b:456>
>>> print t
From str method of Test: a is 123, b is 456
>>> print str(t)
From str method of Test: a is 123, b is 456

If no __str__ method is defined, print t (or print str(t)) will use the result of __repr__ instead

If no __repr__ method is defined then the default is used, which is pretty much equivalent to..

def __repr__(self):
    return "<%s instance at %s>" % (self.__class__.__name__, id(self))
dbr
+1 but your class code's `__str__` is different from the interactive shell's results you give. :P
Chris Lutz
Err, oops.. manually modifying REPL output never ends well. I should probably doctest my posts :P
dbr
Thanks. But, the string formatting type (%) in your example is deprecated. Could you change to the str.format() type? :-)
Ashwin
The `%` string formatting isn't deprecated, from http://docs.python.org/whatsnew/2.6.html "the % operator is *supplemented* by a more powerful string formatting method, format()"
dbr
Dbr: That is true. Do note that the "What's New In Python 3.0" doc also says "format() method [...] The plan is to eventually make this the only API for string formatting, and to start deprecating the % operator in Python 3.1."
Ashwin