473,395 Members | 1,937 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Modules are hashable?!

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?

Python 2.3.3 (#1, May 7 2004, 10:31:40)
[GCC 3.3.3 20040412 (Red Hat Linux 3.3.3-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import sys
hash(sys) -150589324 sys.x = 42
hash(sys) -150589324 foo = {sys:'bar'}
foo[sys]

'bar'
Jul 18 '05 #1
11 1629
Hello Leif,
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?

http://docs.python.org/tut/node11.ht...00000000000000

HTH.
--
------------------------------------------------------------------------
Miki Tebeka <mi*********@zoran.com>
http://tebeka.spymac.net
The only difference between children and adults is the price of the toys
Jul 18 '05 #2
Leif K-Brooks 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?


Most objects in Python are hashable, and also mutable. If you define a
class Foo and create x = Foo(), x will be hashable. But you can also do
x.stuff = 3. So modules appear to be pretty much regular objects, which
are usually hashed by ID -- which will be unique for any two objects.
Try hash(sys) == id(sys) to see for yourself.

Lists, tuples, dicts, strings, and a few other things are odd in that
they're hashed/compared by their contents rather than ID. So you can
have two different objects that are equivalent with regards to hashing
or comparing.

Due to the way hashing works, the hash value is not allowed to change
while it's in a dict. IDs never change, so regular objects have an
unchanging hash value even if you change their contents. For the special
objects, changing the contents would change the hash value, and that's
not allowed.

I think that's how it works, anyway :P

- Jason Lai
Jul 18 '05 #3
Leif K-Brooks <eu*****@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
Jul 18 '05 #4
Jason Lai <jm***@uci.edu> wrote:
...
Lists, tuples, dicts, strings, and a few other things are odd in that
they're hashed/compared by their contents rather than ID. So you can
have two different objects that are equivalent with regards to hashing
or comparing.
Two _distinct_ objects that are not different, actually (this also
applies to numbers -- their values get compared, not their identities).
I think you have the right ideas, just trying to perfect your choice of
words here -- distinct vs different. I think the best usage is:

"A is different from B" -> "A != B"
"A is distinct from B" -> "A is not B"
I think that's how it works, anyway :P


Pretty much, yes.
Alex
Jul 18 '05 #5
Alex Martelli wrote:
Leif K-Brooks <eu*****@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
list, strings, tuples and dictionary. Is there any others that fall into
this category? Is there any way to make them hashable?

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.

Maurice
Jul 18 '05 #6
Maurice LING wrote:

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
list, strings, tuples and dictionary. Is there any others that fall into
this category? Is there any way to make them hashable?
Well, strings and tuples are immutable, so they provide a hash function
(since it's safe to hash them by contents; the contents are pointers
that don't change.) Anything that provides a hash function can be
hashed. You could theoretically create a new list type that works
exactly like a normal list, but hashes based on ID.

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.

Maurice


Heh, like giving every person a unique govt-assigned ID number. You
could have two people who are exactly alike -- cloned atom-by-atom, or
something -- but they wouldn't have the same ID. And the term "hashing"
originates from chopping things up, so hashing humans wouldn't be a good
idea :P

- Jason Lai
Jul 18 '05 #7
On Fri, 03 Sep 2004 04:05:40 GMT, Maurice LING <ma*********@acm.org> wrote:
Alex Martelli wrote:
Leif K-Brooks <eu*****@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
list, strings, tuples and dictionary. Is there any others that fall into
this category? Is there any way to make them hashable?


Define the __hash__ method for the class.

Strings for example, are hashable even though they comparisons are done
with respect to the contents and not the id. Tuples are also:

; python
Python 2.3.4 (#2, Aug 18 2004, 13:18:19)
[GCC 3.3.4 (Debian 1:3.3.4-9)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
t1 = (1,2,3)
t2 = (1,2,3)
id(t1) 1075806412 id(t2) 1075841140 hash(t1) -821448277 hash(t2) -821448277

;

--
Sam Holden
Jul 18 '05 #8
is there actually a practical reason to hash modules? can I call a
module using the hash key?

maurice
Jul 18 '05 #9
Maurice LING <ma*********@acm.org> wrote:
Alex Martelli wrote:
Leif K-Brooks <eu*****@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
Jul 18 '05 #10
Jason Lai <jm***@uci.edu> wrote:
Maurice LING wrote:

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
list, strings, tuples and dictionary. Is there any others that fall into
this category? Is there any way to make them hashable?
Well, strings and tuples are immutable, so they provide a hash function
(since it's safe to hash them by contents; the contents are pointers
that don't change.) Anything that provides a hash function can be


Yes, a tuple's "pointers" don't change, but they may refer to objects
that do, and in this case the tuple need not be hashable. E.g.:
a=tuple([ {} ])
hash(a)

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: dict objects are unhashable

Since the tuple has (as its only item) a dict, the tuple itself isn't
hashable -- the error message indicates the type of the item that fails
to be hashable.
hashed. You could theoretically create a new list type that works
exactly like a normal list, but hashes based on ID.


No, if a==b and hash(a)!=hash(b) all hell would break loose. Don't go
there.
Alex
Jul 18 '05 #11
Maurice LING <ma*********@acm.org> wrote:
is there actually a practical reason to hash modules? can I call a
module using the hash key?


You cannot call a module: a module does not have a __call__ method.
This has nothing to do with hashing.

A practical reason to hash modules would be to associate to each module
some value or group of values -- without sticking those values in the
module itself -- or keep track of a set of modules having some special
characteristic whereby you want to "logically group them together" as
the set of keys into a certain dict (or in 2.4 the elements of a certain
set, since set is now a builtin type).

Consider for example a module that starts:

import foo, fee, fie, fo, fum, bar, baz, bat
yet_untested_modules = dict.fromkeys([ fee, bar, baz ])

later on you might have code like

if somemodule in yet_untested_modules:
somemodule.perform_all_tests()
del yet_untested_modules[somemodule]

for "just in time testing" of a certain set of modules. OK, weird-ish,
but it's what I could come up in 20 seconds;-). To have modules as dict
keys or set members they must be hashable, and since there's no reason
to make them unhashable, why not?
Alex
Jul 18 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Gerrit Holl | last post by:
Hi, why is an xrange object not hashable? I was trying to do something like: comments = { xrange(0, 4): "Few", xrange(4, 10): "Several", xrange(10, 100): "A lot", xrange(100, sys.maxint):...
0
by: Nick Coghlan | last post by:
Anyone playing with the CPython interpreter's new command line switch might have noticed that it only works with top-level modules (i.e. scripts that are directly on sys.path). If the script is...
15
by: Nick Coghlan | last post by:
Python 2.4's -m command line switch only works for modules directly on sys.path. Trying to use it with modules inside packages will fail with a "Module not found" error. This PEP aims to fix that...
4
by: Misto . | last post by:
Hi folks! Short: There is a way to dumplicate a module ? I tried copy.deepcopy(module) but hangs with an error (also with standard modules ).. The only solution that I have by now is...
7
by: Lauren Quantrell | last post by:
At running the risk of asking how big is too big... Is there a rule of thumb or a best practice that says I may have too many modules? I currently have a Access2K app with about 30 code modules,...
13
by: Robin Haswell | last post by:
Hey people I'm an experience PHP programmer who's been writing python for a couple of weeks now. I'm writing quite a large application which I've decided to break down in to lots of modules...
7
by: Andy | last post by:
Hi, I'm trying to search and print any no# of Python keywords present in a text file (say - foo.txt), and getting the above error. Sad for not being able to decipher such a simple problem (I can...
1
by: Simon Pickles | last post by:
Hi, The term 'hashable'. Am I right in thinking it means it can be indexed? like a string or a dict? Thanks Si
3
by: Mohamed Yousef | last post by:
Hello , The problem I'm asking about is how can imported modules be aware of other imported modules so they don't have to re-import them (avoiding importing problems and Consicing code and...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.