hashing mutable instances
Michael Hudson
mwh at python.net
Thu Oct 30 10:14:34 EST 2003
Bernhard Herzog <bh at intevation.de> writes:
> Michael Hudson <mwh at python.net> writes:
>
> > Bernhard Herzog <bh at intevation.de> writes:
> >
> >> IMO it depends on what equality means for instances. E.g. if two
> >> instances are only equal if they're identical, i.e. a == b is equivalent
> >> to a is b, then defining __hash__ can be very useful, because then you
> >> can use them in dictionaries and mutability doesn't really matter
> >> because no change to one instance can make it equal to a nother
> >> instance.
> >
> > Um. In that case why define __hash__ or __eq__ at all?
>
> Good question. I didn't know that that was the default implementation of
> __hash__. It's not documented AFAICT, but it does seem to be the case. I
> wonder why, even though it's useful.
Well, I didn't so much know that this was the default implementation
of __hash__ as know that instances of classes that don't do anything
to the contrary compare equal iff identical and are usefully hashable.
(Python Mystery Theatre question: for such a class, when can you have
id(ob) != hash(ob)?)
> The language reference for __hash__ says:
>
> If a class does not define a __cmp__() method it should not define a
> __hash__() operation either;
>
> Seems a bit outdated in that it only mentions __cmp__ here and not
> __eq__ as well as it does right after the semicolon, but that would not
> indicate to me that hash works for an instance without a hash method.
I hadn't had the distraction of reading this section of the language
reference :-) Did you seriously think that you *had* to define
__hash__ to make instances of your classes hashable?
> Of course the sentence above could be taken to mean that if you
> define neither method the defaults to the right thing, but that
> would seem very obscure to me.
Well, this is Python after all. I would have read
if it defines __cmp__() or __eq__() but not __hash__(), its
instances will not be usable as dictionary keys.
to imply that in other situations that instances would be usable as
dictionary keys.
> Anyway, I've found that if you end up comparing objects very often
> is can be a substantial performance gain if you do define __eq__
> even though it ends up doing the same as the default comparison. At
> least for old style classes when __eq__ is not defined python tries
> __cmp__ and __coerce__ and __getattr__ if defined is called for all
> of them.
Old-style classes? What are they? :-) Didn't know about that.
> Then, once you have defined __eq__ you also need to have __hash__ if you
> want your objects to be hashable.
Yes. I'm glad that bit of silliness is now dead (ish).
Cheers,
mwh
--
We've had a lot of problems going from glibc 2.0 to glibc 2.1.
People claim binary compatibility. Except for functions they
don't like. -- Peter Van Eynde, comp.lang.lisp
More information about the Python-list
mailing list