Search code examples
pythonmethodshashmagic-methods

Python - Using the default __hash__ method in __hash__ method definition


I have a class, and I wish to write a __hash__() method for this class. The method I want to write will return the default hash of the object in some cases, and a hash of one of its attributes in some others. So, as a simple test case:

class Foo:
    def __init__(self, bar):
        self.bar = bar
    def __hash__(self):
        if self.bar < 10:
            return hash(self) # <- this line doesn't work
        else:
            return hash(self.bar)

The problem with this is that hash(self) simply calls self.__hash__(), leading to infinite recursion.

I gather that the hash of an object is based on the id() of that object, so I could rewrite return hash(self) as return id(self), or return id(self) / 16, but it seems bad form to me to recreate the default implementation in my own code.

It also occurred to me that I could rewrite it as return object.__hash__(self). This works, but seems even worse, as special methods are not intended to be called directly.

So, what I'm asking is; is there a way to use the default hash of an object without implicitly calling the __hash__() method of the class that object is an instance of?


Solution

  • To call parent implementation use:

    super(Foo, self).__hash__()
    

    It also occurred to me that I could rewrite it as return object.__hash__(self). This works, but seems even worse, as special methods are not intended to be called directly.

    You are overriding a magic method, so it's ok to call parent's implementation directly.