I recently tried the following commands in Python:
>>> {lambda x: 1: 'a'} {<function __main__.<lambda>>: 'a'} >>> def p(x): return 1 >>> {p: 'a'} {<function __main__.p>: 'a'}
The success of both dict
creations indicates that both lambda and regular functions are hashable. (Something like {[]: 'a'}
fails with TypeError: unhashable type: 'list'
).
The hash is apparently not necessarily the ID of the function:
>>> m = lambda x: 1 >>> id(m) 140643045241584 >>> hash(m) 8790190327599 >>> m.__hash__() 8790190327599
The last command shows that the __hash__
method is explicitly defined for lambda
s, i.e., this is not some automagical thing Python computes based on the type.
What is the motivation behind making functions hashable? For a bonus, what is the hash of a function?
Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally. All of Python's immutable built-in objects are hashable, while no mutable containers (such as lists or dictionaries) are.
__hash__() method. You can check for that. A warning about this: In Python 2.5 this will give: {'test': 'dict'}is hashable . It can also give a wrong result in newer versions if a class defines __hash__ to raise a TypeError.
Python dictionaries only accept hashable data types as a key in a dictionary. A list is not a hashable data type. If you specify a list as a key in a dictionary, you'll encounter a “TypeError: unhashable type: 'list'” error.
An object is said to be hashable if it has a hash value that remains the same during its lifetime.
It's nothing special. As you can see if you examine the unbound __hash__
method of the function type:
>>> def f(): pass ... >>> type(f).__hash__ <slot wrapper '__hash__' of 'object' objects>
the of 'object' objects
part means it just inherits the default identity-based __hash__
from object
. Function ==
and hash
work by identity. The difference between id
and hash
is normal for any type that inherits object.__hash__
:
>>> x = object() >>> id(x) 40145072L >>> hash(x) 2509067
You might think __hash__
is only supposed to be defined for immutable objects, and you'd be almost right, but that's missing a key detail. __hash__
should only be defined for objects where everything involved in ==
comparisons is immutable. For objects whose ==
is based on identity, it's completely standard to base hash
on identity as well, since even if the objects are mutable, they can't possibly be mutable in a way that would change their identity. Files, modules, and other mutable objects with identity-based ==
all behave this way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With