Friday, October 25, 2013

Python: object container's __str__ calls __repr__ for the objects it contains

This should look familiar:
In [6]: class NewShiny(object):
    def __str__(self):
        return "something readable"
   ...: 

In [7]: a = NewShiny()

In [8]: print a
something readable
But have you ever been surprised by this?
In [10]: print [a]
[<__main__.NewShiny object at 0x4ce1590>]
What's happening is that when you call __str__ on the array it is calling __repr__ on all the objects inside the array. So the solution is to define __repr__:
In [15]: class NewShiny(object):
   ....:     def __str__(self):
   ....:         return "something readable"
   ....:     def __repr__(self):
   ....:         return "use this to recreate with eval()"
   ....: 

In [16]: a = NewShiny()

In [21]: print (a)
something readable

In [22]: print [a]
[use this to recreate with eval()]

In [23]: print (a,a)
(use this to recreate with eval(), use this to recreate with eval())
This stackoverflow answer has an excellent explanation of why this is the standard behaviour, and what the difference is between __str__ and __repr__. The general idea with __repr__ is that it returns a string that can be used to re-create the object if passed to eval().

No comments: