Best practise implementation for equal by value objects

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Wed Aug 6 22:34:16 EDT 2008


On Wed, 06 Aug 2008 05:50:35 -0700, Slaunger wrote:

> Hi,
> 
> I am new here and relatively new to Python, so be gentle:
> 
> Is there a recommended generic implementation of __repr__ for objects
> equal by value to assure that eval(repr(x)) == x independet of which
> module the call is made from?

In general, no.

...
> My question is: Is there a robust generic type of implementation of
> __repr__ which I can use instead?
> 
> This is something I plan to reuse for many different Value classes, so I
> would like to get it robust.

I doubt you could get it that robust, nor is it intended to be.

eval(repr(obj)) giving obj is meant as a guideline, not an invariant -- 
there are many things that can break it. For example, here's a module 
with a simple class:


# Parrot module
class Parrot(object):
    def __repr__(self):
        return "parrot.Parrot()"
    def __eq__(self, other):
        # all parrots are equal
        return isinstance(other, Parrot)


Now let's use it:

>>> import parrot
>>> p = parrot.Parrot()
>>> s = repr(p)
>>> assert eval(s) == p
>>> del parrot
>>> assert eval(s) == p
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'parrot' is not defined


If you look at classes in the standard library, they often have reprs 
like this:

>>> repr(timeit.Timer())
'<timeit.Timer instance at 0xb7f14bcc>'

Certainly you can't expect to successfully eval that!

I believe the recommendation for eval(repr(obj)) to give obj again is 
meant as a convenience for the interactive interpreter, and even there 
only for simple types like int or list. If you can do it, great, but if 
it doesn't work, so be it. You're not supposed to rely on it, and it's 
not meant as a general way to serialize classes.


-- 
Steven



More information about the Python-list mailing list