object identity and equivalence

Werner Schiendl ws-news at gmx.at
Mon Nov 19 13:33:50 EST 2001


Hi,

Object identity (is) defines if two things refer to the same instance of an
object.
Equality (==) only informs you that two things refer two instances with the
same value.

For your own classes, you can define how equality should be defined.
E. g.

>>> class Test:
...  def __init__(self, data):
...   self._data = data
...  def __cmp__(self, other):
...   return cmp(self._data, other._data)
...
>>> x = Test(17)
>>> y = Test(17)
>>> z = Test(20)
>>> x is y
0
>>> x == y
1
>>> x is z
0
>>> x == z
0
>>>

x and y in the above example are not the same instance, so is yields 0.
But they have the same value, so == yields 1.

>>> y = x
>>> x is y
1

After assigning x to y, both variables refer to the same instance of the
class.
Now is yields 1.

>>> a = 7
>>> b = 7
>>>
>>> c = 273
>>> d = 273
>>>
>>> a is b
1
>>> a == b
1
>>> c is d
0
>>> c == d
1
>>> c = d
>>> c is d
1

When testing the same thing with integer values, it seems strange why a is b
and c is d do not yield the same value.
Integers are objects in Python, and they are created on demand (e. g. when
you assign a literal value).

However, small literal values are not created, but a reference to a cached
object is handed out.
Therefore, a and b refer to the same (cached) object, whereas a new object
has been created for c and d.

Since you used small integer numbers, you were biten by this optimization of
Python.

As a conclusion, you should use == when you are interested if two variables
refer to the same value.
Use is if you need to know that two variables actually refer to the same
instance.

hth
Werner

"Sandy Norton" <sandskyfly at hotmail.com> wrote in message
news:b03e80d.0111190954.ce015b8 at posting.google.com...
> I apologize if this is a stupid question that has been asked before.
> (I feel kinda stupid asking it :-) but I've searched the FAQ to no
> avail and google is not really responsive to the keywords in question.
> But this question is pestering me...
>
> I am a bit confused about when it is correct to use object identity
> "is" for comparisons and when I should use the equals '==' operator.
>
> I always seem to get the same results with both:
>
> >>> class Person: pass
> ...
> >>> p1 = Person()
> >>> p2 = Person()
> >>> p1 is p1
> 1
> >>> p1 == p1
> 1
> >>> p1 is p2
> 0
> >>> p1 == p2
> 0
> >>> 1.0 is 1.0
> 1
> >>> 1.0 == 1.0
> 1
> >>> 1 is 2
> 0
> >>> 1 == 2
> 0
> >>> (2+3) is 5
> 1
> >>> (2+3) == 5
> 1
>
> I haven't personally come across cases where these two operators don't
> produce the same results with the same operands. Of course I am not
> assuming the semantic equivalence of the operators, as it makes sense
> that comparing object identity is the not the same as comparing object
> value. But could someone offer me an example that uses the same two
> operands with 'is' and '==' and produces 'different' results.
>
> Aside: I'm assuming you can overload the '==' operator but not the
> 'is' operator? Is this true?
>
> There! I've announced my ignorance to the world. Feel better already!
>
> Sandy





More information about the Python-list mailing list