Best practise implementation for equal by value objects

Slaunger Slaunger at gmail.com
Thu Aug 7 02:29:01 EDT 2008


On 7 Aug., 04:34, Steven D'Aprano <st... at REMOVE-THIS-
cybersource.com.au> wrote:
> 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.
>
> ...
>
OK.

> > 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:

OK, I had not fully understood the implications of 'not' implementing
__repr__
such that eval(repr(x)) == x, so I just tried to make it work to make
sure
life would be easy for me and my object as I went further into the
Python jungle

As mentioned above, i also find the eval(repr(x))==x condition
convenient from
a unit test point of view.

>
> # 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
>

OK, I see, but this isn't exactly eval(repr(x))==x but
s = repr(x)
eval(s) == x

so, of course, is s is deleted in between it won't work.

In my implementation I only expect this should work as a one-liner.

> If you look at classes in the standard library, they often have reprs
> like this:
>
> >>> repr(timeit.Timer())
>
> '<timeit.Timer instance at 0xb7f14bcc>'
>

Yes, I noticed that. But the example here is also an object, which is
equal by reference, not value. And for these
it does not make so much sense to evaluate the representation.

> 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

OK, I will put less emphasis on it in the future.

Thank you for taking your time to answer.

Slaunger



More information about the Python-list mailing list