Hash values are just integers which are used to compare dictionary keys during a dictionary lookup quickly.
Internally, hash() method calls __hash__() method of an object which are set by default for any object. We'll look at this later.
The syntax of hash() method is:
The hash() method takes a single parameter:
The hash() method returns the hash value of an object if it has one.
If an object has custom __hash__() method, it truncates the return value to the size of Py_ssize_t.
# hash for integer unchanged
print('Hash for 181 is:', hash(181))
# hash for decimal
print('Hash for 181.23 is:',hash(181.23))
# hash for string
print('Hash for Python is:', hash('Python'))
When you run the program, the output will be:
Hash for 181 is: 181
Hash for 181.23 is: 530343892119126197
Hash for Python is: 2230730083538390373
The hash() method only works for immutable objects as tuple.
# tuple of vowels
vowels = ('a', 'e', 'i', 'o', 'u')
print('The hash is:', hash(vowels))
The hash is: -695778075465126279
As stated above, hash() method internally calls __hash__() method. So, any objects can override the __hash__() for custom hash values.
But for correct hash implementation, __hash__() should always return an integer. And, both __eq__() and __hash__() methods have to be implemented.
Below are the cases for correct __hash__() override.
Class instances will not be usable as hashable collection.
__hash__() implicity set to None
Raises TypeError exception if tried to retrieve the hash.
__hash__ = None
def __init__(self, age, name):
self.age = age
self.name = name
def __eq__(self, other):
return self.age == other.age and self.name == other.name
print('The hash is:')
return hash((self.age, self.name))
person = Person(23, 'Adam')
The hash is:
Note: You don't have to implement the __eq__() method for the hash as it is created by default for all objects.