Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is a python object's hash computed and why is the hash of -1 different?

Tags:

python

hash

Following on from this question, I'm interested to know when is a python object's hash computed?

  1. At an instance's __init__ time,
  2. The first time __hash__() is called,
  3. Every time __hash__() is called, or
  4. Any other opportunity I might be missing?

May this vary depending on the type of the object?

Why does hash(-1) == -2 whilst other integers are equal to their hash?

like image 962
wim Avatar asked Oct 04 '11 12:10

wim


People also ask

How does Python compute hash?

The default hash function ignores the object's attributes and calculates the hash based on the object's id. No matter what changes you make to a0 , its hash will always stay the same. (Though it is possible to define a custom hash function for instances of your A class by implementing a custom __hash__ method.)

What is the hash value of an object Python?

What is Hash Method in Python? Hash method in Python is a module that is used to return the hash value of an object. In programming, the hash method is used to return integer values that are used to compare dictionary keys using a dictionary look up feature.

How does Python compare hash values?

Python hashable In order to perform comparisons, a hashable needs an __eq__ method. Note: Hashable objects which compare equal must have the same hash value. Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.

What is Python __ hash __?

Introduction to the Python hash functionThe hash() function accepts an object and returns the hash value as an integer. When you pass an object to the hash() function, Python will execute the __hash__ special method of the object. It means that when you pass the p1 object to the hash() function: hash(p1)


1 Answers

The hash is generally computed each time it's used, as you can quite easily check yourself (see below). Of course, any particular object is free to cache its hash. For example, CPython strings do this, but tuples don't (see e.g. this rejected bug report for reasons).

The hash value -1 signals an error in CPython. This is because C doesn't have exceptions, so it needs to use the return value. When a Python object's __hash__ returns -1, CPython will actually silently change it to -2.

See for yourself:

class HashTest(object):     def __hash__(self):         print('Yes! __hash__ was called!')         return -1  hash_test = HashTest()  # All of these will print out 'Yes! __hash__ was called!':  print('__hash__ call #1') hash_test.__hash__()  print('__hash__ call #2') hash_test.__hash__()  print('hash call #1') hash(hash_test)  print('hash call #2') hash(hash_test)  print('Dict creation') dct = {hash_test: 0}  print('Dict get') dct[hash_test]  print('Dict set') dct[hash_test] = 0  print('__hash__ return value:') print(hash_test.__hash__())  # prints -1 print('Actual hash value:') print(hash(hash_test))  # prints -2 
like image 111
Petr Viktorin Avatar answered Oct 13 '22 19:10

Petr Viktorin