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?
The == operator compares the value or equality of two objects, whereas the Python is operator checks whether two variables point to the same object in memory. In the vast majority of cases, this means you should use the equality operators == and != , except when you're comparing to None .
Both “is” and “==” are used for object comparison in Python. The operator “==” compares values of two objects, while “is” checks if two objects are same (In other words two references to same object). The “==” operator does not tell us whether x1 and x2 are actually referring to the same object or not.
The is keyword is used to test if two variables refer to the same object. The test returns True if the two objects are the same object. The test returns False if they are not the same object, even if the two objects are 100% equal. Use the == operator to test if two variables are equal.
In Python != is defined as not equal to operator. It returns True if operands on either side are not equal to each other, and returns False if they are equal. Whereas is not operator checks whether id() of two objects is same or not.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With