Reputation: 812
So many tutorials have stated that the ==
comparison operator is for value equality, like in this answer, quote:
==
is for value equality. Use it when you would like to know if two objects have the same value.is
is for reference equality. Use it when you would like to know if two references refer to the same object.
However, I found that the Python doc says that:
x==y
callsx.__eq__(y)
. By default,object
implements__eq__()
by usingis
, returningNotImplemented
in the case of a false comparison:True if x is y else NotImplemented
."
It seems the default behavior of the ==
operator is to compare the reference quality like the is
operator, which contradicts what these tutorials say.
So what exactly should I use ==
for? value equality or reference equality? Or it just depends on how you implement the __eq__
method.
I think the doc of Value comparisons has illustrated this question clearly:
The operators
<
,>
,==
,>=
,<=
, and!=
compare the values of two objects. The value of an object is a rather abstract notion in Python. Comparison operators implement a particular notion of what the value of an object is. One can think of them as defining the value of an object indirectly, by means of their comparison implementation.
The behavior of the default equality comparison, that instances with different identities are always unequal, may be in contrast to what types will need that have a sensible definition of object value and value-based equality. Such types will need to customize their comparison behavior, and in fact, a number of built-in types have done that.
The default behavior for equality comparison (
==
and!=
) is based on the identity of the objects. Hence, equality comparison of instances with the same identity results in equality, and equality comparison of instances with different identities results in inequality. A motivation for this default behavior is the desire that all objects should be reflexive (i.e.x is y
impliesx == y
).
It also includes a list that describes the comparison behavior of the most important built-in types like numbers, strings and sequences, etc.
Upvotes: 5
Views: 4336
Reputation: 29967
object
implements __eq__()
by using is
, but many classes in the standard library implement __eq__()
using value equality. E.g.:
>>> l1 = [1, 2, 3]
>>> l2 = [1, 2, 3]
>>> l3 = l1
>>> l1 is l2
False
>>> l1 == l2
True
>>> l1 is l3
True
In your own classes, you can implement __eq__()
as it makes sense, e.g.:
class Point():
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return self.x == other.x and self.y == other.x
Upvotes: 4
Reputation: 120
one = 1
a = one
b = one
if (a == b): # this if works like this: if (1 == 1)
if (a is 1): # this if works like this: if (int.object(1, memory_location:somewhere) == int.object(1, memory_location:variable.one))
thus, a is 1 won't work because its arguments are not pointing to the same location.
Upvotes: -1
Reputation: 78680
It solely depends on what __eq__
does. The default __eq__
of type object
behaves like is
. Some builtin datatypes use their own implementation. For example, two lists are equal if all their values are equal. You just have to know this.
Upvotes: 3
Reputation: 1749
To add your thought process with a simple definition ,
The Equality operator ==
compares the values of both the operands and checks for value equality. Whereas the is
operator checks whether both the operands refer to the same object or not (present in the same memory location).
In a nutshell, is
checks whether two references point to the same object or not.==
checks whether two objects have the same value or not.
For example:
a=[1,2,3]
b=a #a and b point to the same object
c=list(a) #c points to different object
if a==b:
print('#') #output:#
if a is b:
print('##') #output:##
if a==c:
print('###') #output:##
if a is c:
print('####') #no output as c and a point to different object
Upvotes: 0