Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recommended way to implement __eq__ and __hash__

The python documentation mentions that if you override __eq__ and the object is immutable, you should also override __hash__ in order for the class to be properly hashable.

In practice, when I do this I often end up with code like

class MyClass(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __eq__(self, other):
        if type(other) is type(self):
            return (self.a == other.a) and (self.b == other.b)
        else:
            return False

    def __hash__(self):
        return hash((self.a, self.b))

This is somewhat repetitive, and there is a clear risk of forgetting to update one when the other is updated.

Is there a recommended way of implementing these methods together?

like image 610
Jonas Adler Avatar asked Jul 18 '17 10:07

Jonas Adler


People also ask

What is the __ eq __ method?

Summary. Implement the Python __eq__ method to define the equality logic for comparing two objects using the equal operator ( == )

What does __ hash __ do?

Introduction to the Python hash function The 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.

How do you make a hashable type in Python?

If you want to make your classes hashable, you must follow two rules outlined in the Python Glossary for the entry for "hashable": An object is hashable if [1] it has a hash value which never changes during its lifetime (it needs a __hash__() method), and can be compared to other objects (it needs an __eq__() method).


1 Answers

Answering my own question. It seems one way of performing this is to define an auxillary __members function and to use that in defining __hash__ and __eq__. This way, there is no duplication:

class MyClass(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __members(self):
        return (self.a, self.b)

    def __eq__(self, other):
        if type(other) is type(self):
            return self.__members() == other.__members()
        else:
            return False

    def __hash__(self):
        return hash(self.__members())
like image 62
Jonas Adler Avatar answered Oct 01 '22 02:10

Jonas Adler