8

I am pickling, compressing, and saving python objects. I want to be able to double-check that that the object I saved is the exact same object that is returned after decompression and depickling. I thought there was an error in my code, but when I boiled the problem down to a reproducible example I found that python does not consider two seemingly identical objects created at two different points in time to be equal. Here is a reproducible example:

class fubar(object):
    pass

print(fubar() == fubar())
#False

Why does python consider these two objects to be not equal and what is the most pythonic way to check that two objects are indeed identical?

Michael
  • 13,244
  • 23
  • 67
  • 115

4 Answers4

11

The default equality comparison in Python is to check for identity (i.e. two objects are the same object).

According to the Python Library Reference:

Non-identical instances of a class normally compare as non-equal unless the class defines the __eq__() method or the __cmp__() method.

To create your own definition of equivalence, you need to define an __eq__ method. Here is one way to do it:

class fubar(object):

    def __eq__(self, other):
        'Fubar objects are considered equal if they have the same contents'
        if type(self) != type(other):
            return NotImplemented
        return vars(self) == vars(other)

The return value of NotImplemented signals that fubar doesn't know how to make the comparison and is giving the other object a chance to do the comparison.

The Python Language Reference has this to say about NotImplemented:

This type has a single value. There is a single object with this value. This object is accessed through the built-in name NotImplemented. Numeric methods and rich comparison methods may return this value if they do not implement the operation for the operands provided. (The interpreter will then try the reflected operation, or some other fallback, depending on the operator.) Its truth value is true.

Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
2

They're not the same objects. Check the values of id(fubar()) and id(fubar()) for example. You need to implement your own equality method if you wish to redefine how equality works:

class fubar(object):

    def __eq__(self, other):
        return True # make this more complex

This method should return True when self and other are equal and False otherwise.

Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
0

You need to add an __eq__ method to your class if you want define your own way of comparing two objects.

Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
Xymostech
  • 9,710
  • 3
  • 34
  • 44
0

You should look at this answer. Basically, define your __eq__ method to compare the self.__dict__ of the to objects, which returns a dictionary with the attributes of the object.

Community
  • 1
  • 1
Jules G.M.
  • 3,624
  • 1
  • 21
  • 35