Modules are hashable?!

Alex Martelli aleaxit at yahoo.com
Fri Sep 3 10:26:30 CEST 2004


Maurice LING <mauriceling at acm.org> wrote:

> Alex Martelli wrote:
> 
> > Leif K-Brooks <eurleif at ecritters.biz> wrote:
> > 
> > 
> >>I was just playing around, and noticed that modules seem to be hashable.
> >>Can anyone explain that, especially given the fact that they're mutable?
> > 
> > 
> > Any object x is hashable if type(x) does not expose __eq__ nor __cmp__.
> > In that case, the meaning of x==y for that object is 'x is y', that is,
> > id(x)==id(y), so having hash(x) return id(x) is perfectly functional.
> > Mutation is not a problem if it doesn't affect equality comparisons.
> > 
> > 
> > Alex
> 
> The idea that I get from reading this thread is that objects that can be
> type compared (comparing the contents) are not hashable, and they are

Never said that!  I said the reverse: if objects are compared by id
they're also hashable (in the same way).  "All cats are mammals" does
not imply "all mammals are cats".  Objects can perfectly well be
hashable, AND compared by contents at the same time -- that's where
immutability (of those contents which affect comparison and thus
hashing) is a practical necessity.

"Practical", not theoretical: "def __hash__(self): return 23" will in
fact ensure correct semantics.  Unfortunately, it will do so at the
expense of intolerable performance hits any time a number of objects of
this type are used as dictionary keys... if you know anything about
hashing you can see why this can't fail to be so.

> list, strings, tuples and dictionary. Is there any others that fall into
> this category? Is there any way to make them hashable?

strings are hashable, and so are tuples if all their items are hashable.
That is because they define proper __hash__ methods (or rather the C API
equivalent, of course) that cooperate properly with their __cmp__
methods, basically ensuring that x==y implies hash(x)==hash(y).  But
that's hard to ensure, together with the fact that hash(x) must always
give the same result for a given x, for general mutable containers such
as lists and dicts.


> Hashable objects, on the other hand, are hashed based on say, the 
> pointer address pointing the object or an identifier in the Python VM
> symbol table or something. It's like to say that when you hash a human,
> you get the name and not the physical dimensions of the person. The 
> person can grow fat or slim down, but the name is still the same.

As long as your equality-comparison only relies on immutable
characteristics you're fine.  Unfortunately in most countries it IS
legal to change name at least in some circumstances (e.g. it used to
happen almost automatically to a woman when she married, in many
countries, some time ago...) so this wouldn't work in this case;-).


Alex



More information about the Python-list mailing list